ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-11-27 06:33:24
Exec Total Coverage
Lines: 4200 5230 80.3%
Functions: 294 333 88.3%
Branches: 3247 5300 61.3%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 428 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 428 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 609 void maps_init_game_vars()
67 {
68 609 viewport = {};
69 609 viewport_mode = ViewportMode::CenterAndBound;
70 609 viewport_sprite_uid = 1;
71 609 currscr_for_passive_subscr = -1;
72 609 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 15148885 static bool is_in_scrolling_region(int map, int screen)
78 {
79 15148885 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 9002391984 bool is_in_scrolling_region()
94 {
95 9002391984 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 251455794 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1598 times.
✓ Branch 1 taken 251454196 times.
251455794 if (map != cur_map)
108 1598 return false;
109
110
3/4
✓ Branch 0 taken 251454196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 251441983 times.
✓ Branch 3 taken 12213 times.
251454196 if (screen >= 0 && screen < 128)
111 251441983 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 251455794 }
115
116 244745786 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 243630168 times.
✓ Branch 1 taken 1115618 times.
✓ Branch 2 taken 1115618 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115613 times.
244745786 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 30775186 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 30760496 times.
30775186 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 63793596 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 63594148 times.
✓ Branch 1 taken 199448 times.
63793596 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 42487677 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 42086242 times.
42487677 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 42085118 times.
✓ Branch 1 taken 1124 times.
42086242 if (map == cur_region.map) return current_region_ids[screen];
136
137 1124 return Regions[map].get_region_id(screen);
138 42487677 }
139
140 27276802 int get_current_region_id()
141 {
142 27276802 return get_region_id(cur_map, cur_screen);
143 }
144
145 67246 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 67246 region.map = map;
148
149
2/2
✓ Branch 0 taken 66972 times.
✓ Branch 1 taken 274 times.
67246 if (!is_in_scrolling_region(map, screen))
150 {
151 66972 region.region_id = 0;
152 66972 region.origin_screen = screen;
153 66972 region.origin_screen_x = screen % 16;
154 66972 region.origin_screen_y = screen / 16;
155 66972 region.screen_width = 1;
156 66972 region.screen_height = 1;
157 66972 region.screen_count = 1;
158 66972 region.width = 256;
159 66972 region.height = 176;
160 66972 region_scr_dx = 0;
161 66972 region_scr_dy = 0;
162 66972 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 67246 }
213
214 37532 void load_region(int dmap, int screen)
215 {
216 37532 clear_temporary_screens();
217
218 37532 int map = DMaps[dmap].map;
219 37532 current_region_ids = Regions[map].get_all_region_ids();
220
221 37532 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 37532 cur_screen = cur_region.origin_screen;
223 37532 world_w = cur_region.width;
224 37532 world_h = cur_region.height;
225 37532 region_scr_count = cur_region.screen_count;
226 37532 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 37532 region_num_rpos = cur_region.screen_count*176;
228 37532 scrolling_maze_last_solved_screen = 0;
229
230 37532 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 37766 times.
✓ Branch 1 taken 37532 times.
75298 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 38776 times.
✓ Branch 1 taken 37766 times.
76542 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 38776 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38776 times.
38776 if (screen < 136)
237 {
238 38776 screen_in_current_region[screen] = true;
239 38776 }
240 38776 }
241 37766 }
242
243 37532 mark_current_region_handles_dirty();
244 37532 }
245
246 37532 static void prepare_current_region_handles()
247 {
248 37532 current_region_rpos_handles_dirty = false;
249 37532 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 37880 times.
✓ Branch 1 taken 37532 times.
75412 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 38776 times.
✓ Branch 1 taken 37880 times.
76656 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 38776 int screen = cur_screen + x + y*16;
255 38776 int index_start = current_region_screen_count;
256
2/2
✓ Branch 0 taken 38776 times.
✓ Branch 1 taken 271432 times.
310208 for (int layer = 0; layer <= 6; layer++)
257 {
258 271432 mapscr* scr = get_scr_layer(screen, layer);
259
2/2
✓ Branch 0 taken 95253 times.
✓ Branch 1 taken 176179 times.
271432 if (!scr->is_valid())
260 {
261
1/2
✓ Branch 0 taken 176179 times.
✗ Branch 1 not taken.
176179 if (layer == 0) break;
262 176179 continue;
263 }
264
265 95253 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
266 95253 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
267 95253 current_region_screen_count += 1;
268 95253 }
269
270 38776 int num_handles_for_scr = current_region_screen_count - index_start;
271 38776 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
272 38776 }
273 37880 }
274 37532 }
275
276 1735241536 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
277 {
278 DCHECK(!current_region_rpos_handles_dirty);
279 1735241536 return {current_region_rpos_handles, current_region_screen_count};
280 }
281
282 11484770 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
283 {
284 DCHECK(!current_region_rpos_handles_dirty);
285
2/4
✓ Branch 0 taken 11484770 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11484770 times.
11484770 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
286 return {nullptr, 0};
287
288
2/2
✓ Branch 0 taken 65877 times.
✓ Branch 1 taken 11418893 times.
11484770 if (cur_screen >= 0x80)
289 {
290 DCHECK(scr == origin_scr);
291 65877 return {nullptr, 0};
292 }
293
294 DCHECK(is_in_current_region(scr));
295 11418893 return current_region_rpos_handles_scr[scr->screen];
296 11484770 }
297
298 37532 void mark_current_region_handles_dirty()
299 {
300 37532 current_region_rpos_handles_dirty = true;
301 37532 }
302
303 68006 void delete_temporary_screens(mapscr** screens)
304 {
305
2/2
✓ Branch 0 taken 64741712 times.
✓ Branch 1 taken 68006 times.
64809718 for (int i = 0; i < 136*7; i++)
306 {
307
2/2
✓ Branch 0 taken 267358 times.
✓ Branch 1 taken 64474354 times.
64741712 if (!screens[i])
308 64474354 continue;
309
310 267358 mapscr* scr = screens[i];
311 267358 int num_ffcs = scr->numFFC();
312
2/2
✓ Branch 0 taken 7621503 times.
✓ Branch 1 taken 267358 times.
7888861 for (int i = 0; i < num_ffcs; i++)
313 {
314 7621503 sprite* ffc = &scr->ffcs[i];
315
2/2
✓ Branch 0 taken 7617968 times.
✓ Branch 1 taken 3535 times.
7621503 if (ffc->uid)
316 3535 FFCore.release_sprite_owned_objects(ffc->uid);
317 7621503 }
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267358 times.
267358 delete scr;
319 267358 screens[i] = NULL;
320 267358 }
321 68006 }
322
323 38703 void clear_temporary_screens()
324 {
325 38703 delete_temporary_screens(temporary_screens);
326 38703 origin_scr = nullptr;
327 38703 hero_scr = nullptr;
328 38703 }
329
330 29307 std::vector<mapscr*> take_temporary_scrs()
331 {
332
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
333
2/2
✓ Branch 0 taken 29307 times.
✓ Branch 1 taken 27900264 times.
27929571 for (int i = 0; i < 136*7; i++)
334 27900264 temporary_screens[i] = nullptr;
335
336 29307 return screens;
337
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 }
338
339 15079767 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
340 {
341 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
342
343
2/2
✓ Branch 0 taken 15033185 times.
✓ Branch 1 taken 46582 times.
15079767 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
344 15079767 viewport.w = 256;
345 15079767 viewport.h = 176 + (extended_height_mode ? 56 : 0);
346
347
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 15079407 times.
15079767 if (viewport_mode == ViewportMode::Script)
348 360 return;
349
350
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 15033245 times.
15079407 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
351 {
352 15033245 viewport.x = 0;
353 15033245 viewport.y = 0;
354 15033245 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
356 {
357 // Clamp the viewport to the edges of the region.
358
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
359
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
360 46162 }
361 else if (viewport_mode == ViewportMode::Center)
362 {
363 viewport.x = x - viewport.w/2;
364 viewport.y = y - viewport.h/2;
365 }
366 15079767 }
367
368 15079256 sprite* get_viewport_sprite()
369 {
370 15079256 sprite* spr = sprite::getByUID(viewport_sprite_uid);
371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15079250 times.
15079256 if (!spr)
372 {
373 6 viewport_sprite_uid = 1; // Hero uid.
374 6 spr = &Hero;
375 6 }
376
377 15079256 return spr;
378 }
379
380 6 void set_viewport_sprite(sprite* spr)
381 {
382 6 viewport_sprite_uid = spr->uid;
383 6 }
384
385 15049949 void update_viewport()
386 {
387 15049949 sprite* spr = get_viewport_sprite();
388 15049949 int x = spr->x + spr->txsz*16/2;
389 15049949 int y = spr->y + spr->tysz*16/2;
390 15049949 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
391 15049949 }
392
393 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
394 // freezing if the rect returns is large enough). See:
395 // https://discord.com/channels/876899628556091432/1358483603700449581
396 // https://discord.com/channels/876899628556091432/1130384911983980554
397 //
398 89035648 viewport_t get_sprite_freeze_rect()
399 {
400 89035648 viewport_t freeze_rect = viewport;
401 89035648 int tile_buffer = 3;
402 89035648 freeze_rect.w += 16 * tile_buffer * 2;
403 89035648 freeze_rect.h += 16 * tile_buffer * 2;
404 89035648 freeze_rect.x -= 16 * tile_buffer;
405 89035648 freeze_rect.y -= 16 * tile_buffer;
406 89035648 return freeze_rect;
407 }
408
409 4722 mapscr* determine_hero_screen_from_coords()
410 {
411 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
412 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
413 4722 int dx = x / 256;
414 4722 int dy = y / 176;
415 4722 return get_scr(cur_screen + dx + dy * 16);
416 }
417
418 28218 bool edge_of_region(direction dir)
419 {
420
2/2
✓ Branch 0 taken 28138 times.
✓ Branch 1 taken 80 times.
28218 if (!is_in_scrolling_region()) return true;
421
422 80 int screen_x = Hero.current_screen % 16;
423 80 int screen_y = Hero.current_screen / 16;
424
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
425
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
426
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
427
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
428
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
429 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
430 28218 }
431
432 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
433 // Coordinates are clamped to the world bounds.
434 338109168 int get_screen_for_world_xy(int x, int y)
435 {
436
2/2
✓ Branch 0 taken 316970144 times.
✓ Branch 1 taken 21139024 times.
338109168 if (!is_in_scrolling_region())
437 316970144 return cur_screen;
438
439 21139024 int dx = std::clamp(x, 0, world_w - 1) / 256;
440 21139024 int dy = std::clamp(y, 0, world_h - 1) / 176;
441 21139024 int origin_screen_x = cur_screen % 16;
442 21139024 int origin_screen_y = cur_screen / 16;
443 21139024 int scr_x = origin_screen_x + dx;
444 21139024 int scr_y = origin_screen_y + dy;
445 21139024 return map_scr_xy_to_index(scr_x, scr_y);
446 338109168 }
447
448 31102071 int get_screen_for_rpos(rpos_t rpos)
449 {
450 31102071 int origin_screen_x = cur_screen % 16;
451 31102071 int origin_screen_y = cur_screen / 16;
452 31102071 int screen = static_cast<int32_t>(rpos) / 176;
453 31102071 int scr_x = origin_screen_x + screen%cur_region.screen_width;
454 31102071 int scr_y = origin_screen_y + screen/cur_region.screen_width;
455 31102071 return map_scr_xy_to_index(scr_x, scr_y);
456 }
457
458 837285502 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
459 {
460 DCHECK_LAYER_ZERO_INDEX(layer);
461
2/2
✓ Branch 0 taken 806321394 times.
✓ Branch 1 taken 30964108 times.
837285502 if (!is_in_scrolling_region())
462 806321394 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
463 30964108 int screen = get_screen_for_rpos(rpos);
464 30964108 mapscr* scr = get_scr_layer(screen, layer);
465 30964108 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
466 837285502 }
467
468 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
469 // Coordinates are clamped to the world bounds.
470 3485341900 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
471 {
472 3485341900 x = std::clamp(x, 0, world_w - 1);
473 3485341900 y = std::clamp(y, 0, world_h - 1);
474
475 DCHECK_LAYER_ZERO_INDEX(layer);
476
2/2
✓ Branch 0 taken 3458999422 times.
✓ Branch 1 taken 26342478 times.
3485341900 if (!is_in_scrolling_region())
477 {
478 3458999422 int pos = COMBOPOS(x, y);
479 3458999422 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
480 }
481 26342478 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
482 3485341900 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
486 {
487 DCHECK_LAYER_ZERO_INDEX(layer);
488 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
489 }
490
491 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
492 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
493 63140 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 63140 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
497 }
498
499 25595231 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
500 {
501 DCHECK_LAYER_ZERO_INDEX(layer);
502 25595231 rpos_handle.layer = layer;
503 25595231 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
504 25595231 }
505
506 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
507 // Coordinates are clamped to the world bounds.
508 86712 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
509 {
510 DCHECK_LAYER_ZERO_INDEX(layer);
511
512 86712 x = std::clamp(x, 0, world_w - 1);
513 86712 y = std::clamp(y, 0, world_h - 1);
514
515 86712 auto maybe_ffc_handle = getFFCAt(x, y);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (maybe_ffc_handle)
517 return maybe_ffc_handle.value();
518
519 86712 auto rpos = COMBOPOS_REGION_B(x, y);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (rpos == rpos_t::None)
521 return rpos_handle_t();
522 86712 return get_rpos_handle(rpos, layer);
523 86712 }
524
525 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
526 // directly or via zscript) only last until the next area is loaded (via loadscr).
527
528 // Returns the screen containing the (x, y) world position.
529 1553106016 mapscr* get_scr_for_world_xy(int x, int y)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 1542666616 times.
✓ Branch 1 taken 10439400 times.
1553106016 if (!is_in_scrolling_region()) return origin_scr;
533 10439400 return get_scr(get_screen_for_world_xy(x, y));
534 1553106016 }
535
536 26001360 mapscr* get_scr_for_rpos(rpos_t rpos)
537 {
538 // Quick path, but should work the same without.
539
2/2
✓ Branch 0 taken 25863414 times.
✓ Branch 1 taken 137946 times.
26001360 if (!is_in_scrolling_region()) return origin_scr;
540 137946 return get_scr(get_screen_for_rpos(rpos));
541 26001360 }
542
543 17 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
544 {
545 17 return get_scr_layer(get_screen_for_rpos(rpos), layer);
546 }
547
548 // Note: layer=0 is the base screen, 1 is the first layer, etc.
549 2135642879 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
550 {
551 DCHECK_LAYER_ZERO_INDEX(layer);
552
2/2
✓ Branch 0 taken 2125597665 times.
✓ Branch 1 taken 10045214 times.
2135642879 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
553
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336280 times.
10045214 return layer == 0 ?
554 708934 get_scr_for_world_xy(x, y) :
555 9336280 get_scr_layer(get_screen_for_world_xy(x, y), layer);
556 2135642879 }
557
558 1748725190 int get_region_screen_offset(int screen)
559 {
560 1748725190 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
561 }
562
563 655240230 int get_screen_for_region_index_offset(int offset)
564 {
565 655240230 int scr_dx = offset % cur_region.screen_width;
566 655240230 int scr_dy = offset / cur_region.screen_width;
567 655240230 int screen = cur_screen + scr_dx + scr_dy*16;
568 655240230 return screen;
569 }
570
571 655056392 mapscr* get_scr_for_region_index_offset(int offset)
572 {
573 655056392 int screen = get_screen_for_region_index_offset(offset);
574 655056392 return get_scr(screen);
575 }
576
577 // The screen at (map, screen) must exist.
578 1540994796 mapscr* get_scr(int map, int screen)
579 {
580 1540994796 mapscr* scr = get_scr_maybe(map, screen);
581
1/2
✓ Branch 0 taken 1540994796 times.
✗ Branch 1 not taken.
1540994796 CHECK(scr);
582 1540994796 return scr;
583 }
584
585 841466853 mapscr* get_scr(int screen)
586 {
587 841466853 return get_scr(cur_map, screen);
588 }
589
590 // Returns null if active screen does not exist.
591 1726844943 mapscr* get_scr_maybe(int map, int screen)
592 {
593 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
594
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726844943 times.
1726844943 if (map == cur_map)
596 {
597
2/2
✓ Branch 0 taken 1706018969 times.
✓ Branch 1 taken 20825974 times.
1726844943 if (screen == cur_screen)
598 1706018969 return origin_scr;
599
600 20825974 int index = screen*7;
601
2/2
✓ Branch 0 taken 20802272 times.
✓ Branch 1 taken 23702 times.
20825974 if (temporary_screens[index])
602 20802272 return temporary_screens[index];
603
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23702 times.
23702 if (screen == home_screen)
605 return special_warp_return_scr;
606 23702 }
607
608
4/6
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23700 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23700 times.
23702 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
609 {
610 23700 int index = screen*7;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23700 times.
23700 if (FFCore.ScrollingScreensAll[index])
612 23700 return FFCore.ScrollingScreensAll[index];
613 }
614
615 2 return nullptr;
616 1726844943 }
617
618 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
619 6987491632 mapscr* get_scr_layer(int map, int screen, int layer)
620 {
621 DCHECK_LAYER_ZERO_INDEX(layer);
622
2/2
✓ Branch 0 taken 6290902305 times.
✓ Branch 1 taken 696589327 times.
6987491632 if (layer == 0)
623 696589327 return get_scr(map, screen);
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6290902305 times.
6290902305 if (map == cur_map)
626 {
627 6290902305 int index = screen*7 + layer;
628
2/2
✓ Branch 0 taken 6290758245 times.
✓ Branch 1 taken 144060 times.
6290902305 if (temporary_screens[index])
629 6290758245 return temporary_screens[index];
630
631
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 142200 times.
144060 if (screen == home_screen)
632 1860 return &special_warp_return_scrs[layer];
633 142200 }
634
635
1/2
✓ Branch 0 taken 142200 times.
✗ Branch 1 not taken.
142200 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
636 {
637 142200 int index = screen*7 + layer;
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142200 times.
142200 if (FFCore.ScrollingScreensAll[index])
639 142200 return FFCore.ScrollingScreensAll[index];
640 }
641
642 NOTREACHED();
643 6987491632 }
644
645 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
646 6565340656 mapscr* get_scr_layer(int screen, int layer)
647 {
648 6565340656 return get_scr_layer(cur_map, screen, layer);
649 }
650
651 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
652 // Return nullptr if screen is not valid.
653 419170619 mapscr* get_scr_layer_valid(int screen, int layer)
654 {
655
2/2
✓ Branch 0 taken 98849151 times.
✓ Branch 1 taken 320321468 times.
419170619 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
656 98849151 return scr;
657 320321468 return nullptr;
658 419170619 }
659
660 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
661 {
662 401 int x = get_region_relative_dx(screen);
663 401 int y = get_region_relative_dy(screen);
664
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
665 71 return nullptr;
666
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
667 return nullptr;
668
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
669 return nullptr;
670
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
671 189 return nullptr;
672
673 141 screen = screen_index_direction(screen, dir);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
675 return get_scr(screen);
676
677 141 return nullptr;
678 401 }
679
680 183838 ffc_handle_t get_ffc_handle(ffc_id_t id)
681 {
682 183838 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
683 183838 uint8_t i = id % MAXFFCS;
684 183838 mapscr* scr = get_scr(screen);
685 183838 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
686 183838 return {scr, screen, id, i, ffc};
687 }
688
689 34571 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
690 {
691 34571 x += get_region_relative_dx(screen) * 256;
692 34571 y += get_region_relative_dy(screen) * 176;
693 34571 return {x, y};
694 }
695
696 1056049 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
697 {
698 1056049 int x = get_region_relative_dx(screen) * 256;
699 1056049 int y = get_region_relative_dy(screen) * 176;
700 1056049 return {x, y};
701 }
702
703 12688770636 int32_t COMBOPOS(int32_t x, int32_t y)
704 {
705 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
706 12688770636 return (y & 0xF0) + (x >> 4);
707 }
708 int32_t COMBOPOS_B(int32_t x, int32_t y)
709 {
710 if(unsigned(x) >= 256 || unsigned(y) >= 176)
711 return -1;
712 return (y & 0xF0) + (x >> 4);
713 }
714 3952248331 int32_t COMBOX(int32_t pos)
715 {
716 3952248331 return pos % 16 * 16;
717 }
718 3952248331 int32_t COMBOY(int32_t pos)
719 {
720 3952248331 return pos & 0xF0;
721 }
722
723 116982032 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
724 {
725
2/2
✓ Branch 0 taken 89824080 times.
✓ Branch 1 taken 27157952 times.
116982032 if (!is_in_scrolling_region())
726 89824080 return (rpos_t) COMBOPOS(x, y);
727
728 DCHECK(is_in_world_bounds(x, y));
729 27157952 int scr_dx = x / (16*16);
730 27157952 int scr_dy = y / (11*16);
731 27157952 int pos = COMBOPOS(x%256, y%176);
732 27157952 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 116982032 }
734 6959667904 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
735 {
736
2/2
✓ Branch 0 taken 1546535 times.
✓ Branch 1 taken 6958121369 times.
6959667904 if (!is_in_world_bounds(x, y))
737 1546535 return rpos_t::None;
738
739 6958121369 int scr_dx = x / (16*16);
740 6958121369 int scr_dy = y / (11*16);
741 6958121369 int pos = COMBOPOS(x%256, y%176);
742 6958121369 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
743 6959667904 }
744 27393299 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
745 {
746 27393299 int scr_index = static_cast<int32_t>(rpos) / 176;
747 27393299 int scr_dx = scr_index % cur_region.screen_width;
748 27393299 int scr_dy = scr_index / cur_region.screen_width;
749 27393299 int pos = RPOS_TO_POS(rpos);
750 27393299 int x = scr_dx*16*16 + COMBOX(pos);
751 27393299 int y = scr_dy*11*16 + COMBOY(pos);
752 27393299 return {x, y};
753 }
754 182363 int32_t COMBOX_REGION(rpos_t rpos)
755 {
756 182363 auto [x, y] = COMBOXY_REGION(rpos);
757 182363 return x;
758 }
759 134192 int32_t COMBOY_REGION(rpos_t rpos)
760 {
761 134192 auto [x, y] = COMBOXY_REGION(rpos);
762 134192 return y;
763 }
764
765 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
766 {
767 DCHECK(is_in_world_bounds(x, y));
768
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
769 70177 return (rpos_t)(x + y * 16);
770
771 int scr_dx = x / 16;
772 int scr_dy = y / 11;
773 x %= 16;
774 y %= 11;
775 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
776 70177 }
777 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
778 {
779 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
780 70632 int scr_dx = scr_index % cur_region.screen_width;
781 70632 int scr_dy = scr_index / cur_region.screen_width;
782 70632 int pos = RPOS_TO_POS(rpos);
783 70632 int x = scr_dx*16 + pos%16;
784 70632 int y = scr_dy*11 + pos/16;
785 70632 return {x, y};
786 }
787
788 92320613 int32_t mapind(int32_t map, int32_t screen)
789 {
790 92320613 return map * MAPSCRSNORMAL + screen;
791 }
792
793 FONT *get_zc_font(int index);
794
795 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
796 extern movingblock mblock2; //mblock[4]?
797 extern portal mirror_portal;
798
799 void Z_message_d(const char *format,...)
800 {
801 #ifdef _DEBUG
802 char buf[512];
803 va_list ap;
804 va_start(ap, format);
805 vsprintf(buf, format, ap);
806 va_end(ap);
807
808 al_trace("%s",buf);
809 #else
810 format=format;
811 #endif
812 }
813
814
815
816 bool checktrigger=false;
817
818 void clear_dmap(word i)
819 {
820 DMaps[i].clear();
821 }
822
823 void clear_dmaps()
824 {
825 for(int32_t i=0; i<MAXDMAPS; i++)
826 {
827 clear_dmap(i);
828 }
829 }
830
831 235199467 int32_t isdungeon(int32_t dmap, int32_t screen)
832 {
833
2/2
✓ Branch 0 taken 235152107 times.
✓ Branch 1 taken 47360 times.
235199467 if (dmap < 0) dmap = cur_dmap;
834
835 // dungeons can have any dlevel above 0
836
2/2
✓ Branch 0 taken 133950022 times.
✓ Branch 1 taken 101249445 times.
235199467 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
837 {
838
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
839 9961 return 0;
840
841 101239484 return 1;
842 }
843
844 // dlevels that aren't dungeons are caves
845
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 133913195 times.
133950022 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
846 36827 return 1;
847
848 133913195 return 0;
849 235199467 }
850
851 43127736 int32_t isdungeon(int32_t screen)
852 {
853 43127736 return isdungeon(cur_dmap, screen);
854 }
855
856 191939587 int32_t isdungeon()
857 {
858 191939587 return isdungeon(cur_dmap, Hero.current_screen);
859 }
860
861 92461 bool canPermSecret(int32_t dmap, int32_t screen)
862 {
863
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 78551 times.
92461 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
864 }
865
866 1261772114 int32_t MAPCOMBO(int32_t x, int32_t y)
867 {
868 1261772114 x = vbound(x, 0, world_w-1);
869 1261772114 y = vbound(y, 0, world_h-1);
870 1261772114 int pos = COMBOPOS(x%256, y%176);
871 1261772114 mapscr* scr = get_scr_for_world_xy(x, y);
872 1261772114 return scr->data[pos];
873 }
874
875 //specific layers 1 to 6
876 1488678436 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
877 {
878 DCHECK(layer >= 1 && layer <= 6);
879
3/4
✓ Branch 0 taken 1468774982 times.
✓ Branch 1 taken 19903454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1468774982 times.
1488678436 if (!is_in_world_bounds(x, y) || layer <= 0)
880 19903454 return 0;
881
882 1468774982 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
883
2/2
✓ Branch 0 taken 472762734 times.
✓ Branch 1 taken 996012248 times.
1468774982 if (!m->is_valid())
884 996012248 return 0;
885
886 472762734 int pos = COMBOPOS(x%256, y%176);
887 472762734 return m->data[pos];
888 1488678436 }
889
890 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
891 {
892 DCHECK(layer >= 1 && layer <= 6);
893 if (!is_in_world_bounds(x, y) || layer <= 0)
894 return 0;
895
896 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
897 if (!m->is_valid())
898 return 0;
899
900 int pos = COMBOPOS(x%256, y%176);
901 return m->cset[pos];
902 }
903
904 372352 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
905 {
906 DCHECK(layer >= 1 && layer <= 6);
907
2/4
✓ Branch 0 taken 372352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 372352 times.
372352 if (!is_in_world_bounds(x, y) || layer <= 0)
908 return 0;
909
910 372352 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
911
2/2
✓ Branch 0 taken 345286 times.
✓ Branch 1 taken 27066 times.
372352 if (!m->is_valid())
912 27066 return 0;
913
914 345286 int pos = COMBOPOS(x%256, y%176);
915 345286 return m->sflag[pos];
916 372352 }
917
918 40979 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
919 {
920 DCHECK(layer >= 1 && layer <= 6);
921
2/4
✓ Branch 0 taken 40979 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40979 times.
40979 if (!is_in_world_bounds(x, y) || layer <= 0)
922 return 0;
923
924 40979 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
925
2/2
✓ Branch 0 taken 40624 times.
✓ Branch 1 taken 355 times.
40979 if (!m->is_valid())
926 355 return 0;
927
928 40624 int pos = COMBOPOS(x%256, y%176);
929 40624 return combobuf[m->data[pos]].type;
930 40979 }
931
932 371064 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
933 {
934 DCHECK(layer >= 1 && layer <= 6);
935
2/4
✓ Branch 0 taken 371064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 371064 times.
371064 if (!is_in_world_bounds(x, y) || layer <= 0)
936 return 0;
937
938 371064 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
939
2/2
✓ Branch 0 taken 343998 times.
✓ Branch 1 taken 27066 times.
371064 if (!m->is_valid())
940 27066 return 0;
941
942 343998 int pos = COMBOPOS(x%256, y%176);
943 343998 return combobuf[m->data[pos]].flag;
944 371064 }
945
946 // True if the FFC covers x, y and is not ethereal or a changer.
947 2536388256 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
948 {
949
2/2
✓ Branch 0 taken 750008244 times.
✓ Branch 1 taken 1786380012 times.
2536388256 if (ffc_handle.data() <= 0)
950 750008244 return false;
951
952
2/2
✓ Branch 0 taken 285071207 times.
✓ Branch 1 taken 1501308805 times.
1786380012 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
953 285071207 return false;
954
955 1501308805 int32_t fx = ffc_handle.ffc->x.getInt();
956 1501308805 int32_t w = ffc_handle.scr->ffEffectWidth(ffc_handle.i) - 1;
957
2/2
✓ Branch 0 taken 1390953542 times.
✓ Branch 1 taken 110355263 times.
1501308805 if (static_cast<uint32_t>(x - fx) > static_cast<uint32_t>(w))
958 1390953542 return false;
959
960 110355263 int32_t fy = ffc_handle.ffc->y.getInt();
961 110355263 int32_t h = ffc_handle.scr->ffEffectHeight(ffc_handle.i) - 1;
962
2/2
✓ Branch 0 taken 90405363 times.
✓ Branch 1 taken 19949900 times.
110355263 if (static_cast<uint32_t>(y - fy) > static_cast<uint32_t>(h))
963 90405363 return false;
964
965 19949900 return true;
966 2536388256 }
967
968 829871694 int32_t MAPFFCOMBO(int32_t x,int32_t y)
969 {
970
2/2
✓ Branch 0 taken 11864553 times.
✓ Branch 1 taken 818007141 times.
829871694 if (auto ffc_handle = getFFCAt(x, y))
971 11864553 return ffc_handle->data();
972 818007141 return 0;
973 829871694 }
974
975 207232 int32_t MAPCSET(int32_t x, int32_t y)
976 {
977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
978 return 0;
979 207232 mapscr* scr = get_scr_for_world_xy(x, y);
980 207232 int pos = COMBOPOS(x%256, y%176);
981 207232 return scr->cset[pos];
982 207232 }
983
984 87058385 int32_t MAPFLAG(int32_t x, int32_t y)
985 {
986
2/2
✓ Branch 0 taken 28507 times.
✓ Branch 1 taken 87029878 times.
87058385 if (!is_in_world_bounds(x, y))
987 28507 return 0;
988 87029878 mapscr* scr = get_scr_for_world_xy(x, y);
989 87029878 int pos = COMBOPOS(x%256, y%176);
990 87029878 return scr->sflag[pos];
991 87058385 }
992
993 95535100 int32_t COMBOTYPE(int32_t x,int32_t y)
994 {
995 95535100 int32_t b=1;
996
2/2
✓ Branch 0 taken 64699776 times.
✓ Branch 1 taken 30835324 times.
95535100 if(x&8) b<<=2;
997
2/2
✓ Branch 0 taken 60203017 times.
✓ Branch 1 taken 35332083 times.
95535100 if(y&8) b<<=1;
998
999
2/2
✓ Branch 0 taken 191062453 times.
✓ Branch 1 taken 95519863 times.
286582316 for (int32_t i = 0; i <= 1; ++i)
1000 {
1001
2/2
✓ Branch 0 taken 158746602 times.
✓ Branch 1 taken 32315851 times.
191062453 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1002 {
1003
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158746602 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158746602 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1004 158746602 }
1005 else
1006 {
1007
4/4
✓ Branch 0 taken 18389 times.
✓ Branch 1 taken 32297462 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 15237 times.
32315851 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1008 }
1009 191047216 }
1010
1011 95519863 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1012
5/6
✓ Branch 0 taken 3536051 times.
✓ Branch 1 taken 91983812 times.
✓ Branch 2 taken 1909070 times.
✓ Branch 3 taken 1626981 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909070 times.
95519863 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1013 {
1014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909070 times.
1909070 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1015
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909070 times.
1909070 if(cmb.usrflags&cflag3) return cNONE;
1016 1909070 }
1017 95519863 return cmb.type;
1018 95535100 }
1019
1020 59029550 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1021 {
1022 59029550 return combobuf[MAPFFCOMBO(x,y)].type;
1023 }
1024
1025 7153709 int32_t FFORCOMBO(int32_t x, int32_t y)
1026 {
1027
2/2
✓ Branch 0 taken 78428 times.
✓ Branch 1 taken 7075281 times.
7153709 if (auto ffc_handle = getFFCAt(x, y))
1028 78428 return ffc_handle->data();
1029
1030 7075281 return MAPCOMBO(x,y);
1031 7153709 }
1032
1033 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1034 {
1035 for (int32_t i = 0; i <= 1; ++i)
1036 {
1037 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1038 {
1039 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1040 }
1041 else
1042 {
1043 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1044 }
1045 }
1046 int32_t b=1;
1047
1048 if(x&8) b<<=2;
1049
1050 if(y&8) b<<=1;
1051 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1052 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1053 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1054 return cmb.type;
1055 }
1056
1057 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1058 {
1059 if (auto ffc_handle = getFFCAt(x, y))
1060 return ffc_handle->data();
1061
1062 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1063 }
1064
1065 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1066 {
1067 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1068 }
1069
1070 83411179 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1071 {
1072
2/2
✓ Branch 0 taken 28219 times.
✓ Branch 1 taken 83382960 times.
83411179 if (!is_in_world_bounds(x, y))
1073 28219 return 0;
1074
1075 83382960 mapscr* scr = get_scr_for_world_xy(x, y);
1076 83382960 int pos = COMBOPOS(x%256, y%176);
1077 83382960 return combobuf[scr->data[pos]].flag;
1078 83411179 }
1079
1080 68112056 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1081 {
1082
2/2
✓ Branch 0 taken 777663 times.
✓ Branch 1 taken 67334393 times.
68112056 if (auto ffc_handle = getFFCAt(x, y))
1083 777663 return ffc_handle->cflag();
1084
1085 67334393 return 0;
1086 68112056 }
1087
1088 1237814574 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1089 {
1090 2784780365 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1091 1546965791 return ffcIsAt(ffc_handle, x, y);
1092 });
1093 }
1094
1095 3051 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1096 {
1097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3051 times.
3051 if (!rpos_handle.scr->is_valid()) return 0;
1098 3051 return rpos_handle.data();
1099 3051 }
1100
1101 3016023750 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1102 {
1103 DCHECK_LAYER_NEG1_INDEX(layer);
1104
2/2
✓ Branch 0 taken 22047041 times.
✓ Branch 1 taken 2993976709 times.
3016023750 if (!is_in_world_bounds(x, y)) return 0;
1105
2/2
✓ Branch 0 taken 2896991596 times.
✓ Branch 1 taken 96985113 times.
2993976709 if (layer == -1) return MAPCOMBO(x, y);
1106
1107 2896991596 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1108
2/2
✓ Branch 0 taken 1796540851 times.
✓ Branch 1 taken 1100450745 times.
2896991596 if (!rpos_handle.scr->is_valid()) return 0;
1109
1110 1100450745 return rpos_handle.data();
1111 3016023750 }
1112
1113 19162646 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1114 {
1115 19162646 auto cid = handle.data();
1116 19162646 auto* cmb = &handle.combo();
1117 19162646 bool done = false;
1118 19162646 std::set<int32_t> visited;
1119
2/2
✓ Branch 0 taken 19162646 times.
✓ Branch 1 taken 19162646 times.
38325292 while(!done)
1120 {
1121
2/4
✓ Branch 0 taken 19162646 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19162646 times.
19162646 if(visited.contains(cid))
1122 {
1123 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1124 break; // prevent infinite loop
1125 }
1126
1/2
✓ Branch 0 taken 19162646 times.
✗ Branch 1 not taken.
19162646 visited.insert(cid);
1127
1128 19162646 done = true; // don't loop again unless something changes
1129
1/2
✓ Branch 0 taken 19162646 times.
✗ Branch 1 not taken.
20048209 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1130 885563 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1131 });
1132
2/4
✓ Branch 0 taken 19162646 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19162646 times.
19162646 if(handle.data() != cid)
1133 {
1134 cid = handle.data();
1135 cmb = &handle.combo();
1136 done = false; // loop again for the new combo
1137 }
1138 }
1139 19162646 }
1140 52908 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1141 {
1142 52908 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1143 52908 }
1144 36498 void handle_region_load_trigger()
1145 {
1146
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 36346 times.
36498 if (is_in_scrolling_region())
1147 {
1148
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1149 {
1150
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1151 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1152 19456 }
1153 152 }
1154 36346 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1155 36498 }
1156
1157 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1158 {
1159 15262 auto screen_handles = create_screen_handles_one(&scr);
1160
1161
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1162 {
1163 539 reveal_hidden_stairs(&scr, screen, false);
1164 539 bool do_layers = false;
1165 539 bool from_active_screen = false;
1166 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1167 539 }
1168
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1169 {
1170 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1171 if (rpos_handle.ctype() == cLIGHTTARGET)
1172 {
1173 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1174 rpos_handle.increment_data();
1175 }
1176 });
1177 }
1178
1179 15262 int lvl = DMaps[cur_dmap].level;
1180 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1181 15262 toggle_gswitches_load(screen_handles);
1182
1183
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1184 {
1185 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1186 92 }
1187
1188
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1189 {
1190 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1191 }
1192
1193
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1194 {
1195 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1196 }
1197
1198
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1199 {
1200 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1201 }
1202
1203
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1204 {
1205 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1206 }
1207
1208
1209 15262 int mi = mapind(map, screen);
1210 15262 clear_xdoors_mi(screen_handles, mi);
1211 15262 clear_xstatecombos_mi(screen_handles, mi);
1212
1213 15262 handle_screen_load_trigger(screen_handles);
1214 15262 }
1215
1216 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1217 {
1218
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1219 return std::nullopt;
1220
1221 40981 const mapscr* source = get_canonical_scr(map, screen);
1222
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1223 1725 return std::nullopt;
1224
1225
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1226 {
1227
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1228 23994 return std::nullopt;
1229
1230 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1231
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1232 return std::nullopt;
1233 7326 }
1234
1235
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1236 15262 mapscr scr = *source;
1237
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1238
1239
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1240 40981 }
1241
1242 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1243 {
1244
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1245
1246
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1247 return 0;
1248
1249 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1250 // `apply_state_changes_to_screen` checks).
1251
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1252 4736 return s->data[pos];
1253
1254 10254 return 0;
1255 14990 }
1256
1257 // Read from the current temporary screens or, if (map, screen) is not loaded,
1258 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1259 251444321 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1260 {
1261 DCHECK_LAYER_NEG1_INDEX(layer);
1262 DCHECK(map >= 0 && screen >= 0);
1263
1264
2/2
✓ Branch 0 taken 251429331 times.
✓ Branch 1 taken 14990 times.
251444321 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1265
1266 // Screen is not in the current region, so we have to load and trigger some secrets.
1267 14990 int pos = COMBOPOS(x, y);
1268 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1269 251444321 }
1270
1271 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1272 {
1273 DCHECK_LAYER_NEG1_INDEX(layer);
1274 DCHECK(map >= 0 && screen >= 0);
1275 DCHECK(is_valid_rpos(rpos));
1276
1277 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1278
1279 // Screen is not currently loaded, so we have to load and trigger some secrets.
1280 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1281 }
1282
1283 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1284 {
1285 DCHECK_LAYER_NEG1_INDEX(layer);
1286 if (!is_in_world_bounds(x, y))
1287 return 0;
1288 if (layer == -1) return MAPCSET(x, y);
1289
1290 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1291 if (!rpos_handle.scr->is_valid()) return 0;
1292
1293 return rpos_handle.cset();
1294 }
1295
1296 102412209 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1297 {
1298 DCHECK_LAYER_NEG1_INDEX(layer);
1299
3/4
✓ Branch 0 taken 5385623 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 5385623 times.
✗ Branch 3 not taken.
102412209 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1300 return 0;
1301
2/2
✓ Branch 0 taken 84274547 times.
✓ Branch 1 taken 18137662 times.
102412209 if (layer == -1) return MAPFLAG(x, y);
1302
1303 84274547 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1304
2/2
✓ Branch 0 taken 63730019 times.
✓ Branch 1 taken 20544528 times.
84274547 if (!rpos_handle.scr->is_valid()) return 0;
1305
1306 20544528 return rpos_handle.sflag();
1307 102412209 }
1308
1309 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1310 {
1311 if(layer < 1)
1312 {
1313 for (int32_t i = layer+1; i <= 1; ++i)
1314 {
1315 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1316 {
1317 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1318 }
1319 else
1320 {
1321 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1322 }
1323 }
1324 }
1325 if(layer==-1) return COMBOTYPE(x,y);
1326
1327 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1328 if (!rpos_handle.scr->is_valid()) return 0;
1329
1330 return rpos_handle.ctype();
1331 }
1332
1333 // Returns the flag for the combo at the given position.
1334 // This is also known as an "inherent flag".
1335 100578885 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1336 {
1337 DCHECK_LAYER_NEG1_INDEX(layer);
1338
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 100578597 times.
100578885 if (!is_in_world_bounds(x, y))
1339 288 return 0;
1340
2/2
✓ Branch 0 taken 84177975 times.
✓ Branch 1 taken 16400622 times.
100578597 if (layer == -1) return MAPCOMBOFLAG(x, y);
1341
1342 84177975 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1343
2/2
✓ Branch 0 taken 63748345 times.
✓ Branch 1 taken 20429630 times.
84177975 if (!rpos_handle.scr->is_valid()) return 0;
1344
1345 20429630 return rpos_handle.cflag();
1346 100578885 }
1347
1348 11731751 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1349 {
1350 DCHECK_LAYER_ZERO_INDEX(layer);
1351 11731751 auto rpos_handle = get_rpos_handle(rpos, layer);
1352
2/2
✓ Branch 0 taken 4501350 times.
✓ Branch 1 taken 7230401 times.
11731751 if (!rpos_handle.scr->is_valid()) return false;
1353
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7225836 times.
7230401 if (rpos_handle.sflag() == flag) return true;
1354
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7188131 times.
7225836 if (rpos_handle.cflag() == flag) return true;
1355 7188131 return false;
1356 11731751 }
1357
1358 1712049 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1359 {
1360 DCHECK(is_valid_rpos(rpos));
1361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1712049 times.
1712049 if (rpos > region_max_rpos) return false;
1362
1363
2/2
✓ Branch 0 taken 11731751 times.
✓ Branch 1 taken 1669779 times.
13401530 for(auto q = 0; q < 7; ++q)
1364 {
1365
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11689481 times.
11731751 if(HASFLAG(flag, q, rpos))
1366 42270 return true;
1367 11689481 }
1368 1669779 return false;
1369 1712049 }
1370
1371 const char *screenstate_string[32] =
1372 {
1373 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1374 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1375 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1376 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1377 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1378 };
1379
1380 36563 void eventlog_mapflags()
1381 {
1382 36563 std::ostringstream oss;
1383
1384 36563 int mi = mapind(cur_map, home_screen);
1385
1/2
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
36563 dword g = game->maps[mi];
1386
1387
2/4
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36563 times.
✗ Branch 3 not taken.
36563 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1388
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 20853 times.
36563 if(g) // Main States
1389 {
1390 static const int order[] =
1391 {
1392 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1393 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1394 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1395 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1396 };
1397
1398
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << " [";
1399 15710 bool comma = false;
1400
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 251360 times.
267070 for(int fl : order)
1401 {
1402
2/2
✓ Branch 0 taken 9640 times.
✓ Branch 1 taken 241720 times.
251360 if(!(g&fl))
1403 241720 continue;
1404 9640 byte ind = byte(log2(double(fl)));
1405
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 7568 times.
9640 if(comma)
1406
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 oss << ", ";
1407
1/2
✓ Branch 0 taken 9640 times.
✗ Branch 1 not taken.
9640 oss << screenstate_string[ind];
1408 9640 comma = true;
1409 }
1410
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << "]";
1411 15710 }
1412
3/4
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 36507 times.
36563 if(game->xstates[mi]) // ExStates
1413 {
1414
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << " Ex[";
1415 56 bool comma = false;
1416
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1792 times.
1848 for(byte fl = 0; fl < 32; ++fl)
1417 {
1418
3/4
✓ Branch 0 taken 1792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1715 times.
1792 if(game->xstates[mi] & (1<<fl))
1419 {
1420
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 56 times.
77 if(comma)
1421
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 oss << ", ";
1422
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 oss << int(fl);
1423 77 comma = true;
1424 77 }
1425 1792 }
1426
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << "]";
1427 56 }
1428 { // ExDoors
1429
2/2
✓ Branch 0 taken 36563 times.
✓ Branch 1 taken 146252 times.
182815 for(int q = 0; q < 4; ++q)
1430 {
1431 146252 bool comma = false;
1432
3/4
✓ Branch 0 taken 146252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146250 times.
✓ Branch 3 taken 2 times.
146252 if(auto v = game->xdoors[mi][q])
1433 {
1434
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1435 oss << ",";
1436
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1437
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1438
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1439
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1440
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1441
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1442 2 comma = true;
1443 2 }
1444 146252 }
1445 }
1446
2/4
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36563 times.
36563 Z_eventlog("%s\n", oss.str().c_str());
1447 36563 }
1448
1449 // set specific flag
1450 5932 void setmapflag(mapscr* scr, uint32_t flag)
1451 {
1452
2/2
✓ Branch 0 taken 5919 times.
✓ Branch 1 taken 13 times.
5932 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1453 5932 int mi = mapind(cur_map, scr->screen);
1454 5932 setmapflag_mi(scr, mi, flag);
1455 5932 }
1456 57 void setmapflag_homescr(uint32_t flag)
1457 {
1458 57 int mi = mapind(cur_map, home_screen);
1459 57 setmapflag_mi(origin_scr, mi, flag);
1460 57 }
1461 2065 void setmapflag_mi(int32_t mi, uint32_t flag)
1462 {
1463 2065 byte cscr = mi&((1<<7)-1);
1464 2065 byte cmap = (mi>>7);
1465 2065 mapscr* scr = origin_scr;
1466
2/2
✓ Branch 0 taken 835 times.
✓ Branch 1 taken 1230 times.
2065 if (is_in_current_region(cmap, cscr))
1467 1230 scr = get_scr(cmap, cscr);
1468
1469 2065 setmapflag_mi(scr, mi, flag);
1470 2065 }
1471
1472 8877 static void log_state_change(int map, int screen, std::string action)
1473 {
1474
6/6
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 6940 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8877 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1475 7292 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1476 else
1477 1585 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1478 8877 }
1479
1480 8054 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1481 {
1482 8054 byte cscr = mi&((1<<7)-1);
1483 8054 byte cmap = (mi>>7);
1484
1485 8054 double temp=log2((double)flag);
1486
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1487 8054 const char* replay_state_string = state_string;
1488
2/2
✓ Branch 0 taken 7534 times.
✓ Branch 1 taken 520 times.
8054 if(temp == 6) replay_state_string = "No Return";
1489
1490
3/4
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 6458 times.
8054 if (replay_is_active() && !(game->maps[mi] & flag))
1491
1/2
✓ Branch 0 taken 6458 times.
✗ Branch 1 not taken.
6458 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1492 8054 game->maps[mi] |= flag;
1493
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1494
1495
2/2
✓ Branch 0 taken 2518 times.
✓ Branch 1 taken 5536 times.
8054 if((scr->nocarry&flag)!=flag)
1496 {
1497 5536 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1498 5536 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1499
1500 5536 std::vector<int32_t> done;
1501
2/2
✓ Branch 0 taken 5423 times.
✓ Branch 1 taken 113 times.
5536 bool looped = (nmap==cmap+1 && nscr==cscr);
1502
1503
6/6
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 5485 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 407 times.
✓ Branch 4 taken 407 times.
✓ Branch 5 taken 5536 times.
5943 while((nmap!=0) && !looped && !(nscr>=128))
1504 {
1505
3/4
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 216 times.
407 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1506 {
1507
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 log_state_change(nmap, nscr, "State change carried over");
1508
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 if (replay_is_active())
1509
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1510
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 game->maps[((nmap-1)<<7)+nscr] |= flag;
1511 216 }
1512
1513 407 cmap=nmap;
1514 407 cscr=nscr;
1515 407 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1516 407 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1517
1518
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 407 times.
1323 for(auto it = done.begin(); it != done.end(); it++)
1519 {
1520
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 51 times.
916 if(*it == ((nmap-1)<<7)+nscr)
1521 51 looped = true;
1522 916 }
1523
1524
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 done.push_back(((nmap-1)<<7)+nscr);
1525 }
1526 5536 }
1527 8054 }
1528
1529 void unsetmapflag_home(uint32_t flag, bool anyflag)
1530 {
1531 int mi = mapind(cur_map, home_screen);
1532 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1533 }
1534
1535 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1536 {
1537 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1538 int mi = mapind(cur_map, scr->screen);
1539 unsetmapflag_mi(scr, mi, flag, anyflag);
1540 }
1541
1542 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1543 {
1544 471 byte cscr = mi&((1<<7)-1);
1545 471 byte cmap = (mi>>7);
1546 471 mapscr* scr = origin_scr;
1547
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1548 11 scr = get_scr(cmap, cscr);
1549
1550 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1551 471 }
1552
1553 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1554 {
1555 471 byte cscr = mi&((1<<7)-1);
1556 471 byte cmap = (mi>>7);
1557
1558
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1559 460 game->maps[mi] &= ~flag;
1560
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1561 {
1562 if(!(scr->flags4&fNOITEMRESET))
1563 game->maps[mi] &= ~flag;
1564 }
1565 11 else game->maps[mi] &= ~flag;
1566
1567 471 double temp=log2((double)flag);
1568
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1569
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1570
1571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1572 {
1573 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1574 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1575
1576 471 std::vector<int32_t> done;
1577
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1578
1579
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1580 {
1581
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1582 {
1583
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1584
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1585 72 }
1586
1587 84 cmap=nmap;
1588 84 cscr=nscr;
1589 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1590 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1591
1592
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1593 {
1594
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1595 6 looped = true;
1596 546 }
1597
1598
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1599 }
1600 471 }
1601 471 }
1602
1603 45525988 bool getmapflag(int32_t screen, uint32_t flag)
1604 {
1605
2/2
✓ Branch 0 taken 1164399 times.
✓ Branch 1 taken 44361589 times.
45525988 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1606 45525988 return (game->maps[mi] & flag) != 0;
1607 }
1608 6411006 bool getmapflag(mapscr* scr, uint32_t flag)
1609 {
1610
2/2
✓ Branch 0 taken 181526 times.
✓ Branch 1 taken 6229480 times.
6411006 int mi = mapind(scr->map, scr->screen >= 0x80 ? home_screen : scr->screen);
1611 6411006 return (game->maps[mi] & flag) != 0;
1612 }
1613
1614 57 void setxmapflag(int32_t screen, uint32_t flag)
1615 {
1616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1617 57 setxmapflag_mi(mi, flag);
1618 57 }
1619 59 void setxmapflag_mi(int32_t mi, uint32_t flag)
1620 {
1621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if(game->xstates[mi] & flag) return;
1622 59 byte cscr = mi&((1<<7)-1);
1623 59 byte cmap = (mi>>7);
1624
1625 59 byte temp=(byte)log2((double)flag);
1626
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1627
1628 59 game->xstates[mi] |= flag;
1629
1630 59 mapscr* scr = origin_scr;
1631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (is_in_current_region(cmap, cscr))
1632 59 scr = get_scr(cmap, cscr);
1633
1634
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if((scr->exstate_carry&flag)==flag)
1635 {
1636 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1637 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1638
1639 std::vector<int32_t> done;
1640 bool looped = (nmap==cmap+1 && nscr==cscr);
1641
1642 while((nmap!=0) && !looped && !(nscr>=128))
1643 {
1644 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1645 {
1646 log_state_change(nmap, nscr, "ExState change carried over");
1647 if (replay_is_active())
1648 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1649 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1650 }
1651
1652 cmap=nmap;
1653 cscr=nscr;
1654 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1655 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1656
1657 for(auto it = done.begin(); it != done.end(); it++)
1658 {
1659 if(*it == ((nmap-1)<<7)+nscr)
1660 looped = true;
1661 }
1662
1663 done.push_back(((nmap-1)<<7)+nscr);
1664 }
1665 }
1666 59 }
1667 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1668 {
1669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1670 2 unsetxmapflag_mi(mi, flag);
1671 2 }
1672 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1673 {
1674
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1675 1 byte cscr = mi&((1<<7)-1);
1676 1 byte cmap = (mi>>7);
1677 1 byte temp=(byte)log2((double)flag);
1678
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1679 1 game->xstates[mi] &= ~flag;
1680
1681 1 mapscr* scr = origin_scr;
1682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1683 1 scr = get_scr(cmap, cscr);
1684
1685
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1686 {
1687 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1688 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1689
1690 std::vector<int32_t> done;
1691 bool looped = (nmap==cmap+1 && nscr==cscr);
1692
1693 while((nmap!=0) && !looped && !(nscr>=128))
1694 {
1695 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1696 {
1697 log_state_change(nmap, nscr, "ExState change carried over");
1698 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1699 }
1700
1701 cmap=nmap;
1702 cscr=nscr;
1703 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1704 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1705
1706 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1707 {
1708 if(*it == ((nmap-1)<<7)+nscr)
1709 looped = true;
1710 }
1711
1712 done.push_back(((nmap-1)<<7)+nscr);
1713 }
1714 }
1715 2 }
1716 82 bool getxmapflag(int32_t screen, uint32_t flag)
1717 {
1718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1719 82 return getxmapflag_mi(mi, flag);
1720 }
1721 bool getxmapflag(mapscr* scr, uint32_t flag)
1722 {
1723 int mi = mapind(scr->map, scr->screen >= 0x80 ? home_screen : scr->screen);
1724 return getxmapflag_mi(mi, flag);
1725 }
1726 488427808 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1727 {
1728 488427808 return (game->xstates[mi] & flag) != 0;
1729 }
1730
1731 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1732 {
1733
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1734 return;
1735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1736 return;
1737
1738
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1739
1740 4 int cscr = mi % MAPSCRSNORMAL;
1741 4 int cmap = mi / MAPSCRSNORMAL;
1742
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1743
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1744 else
1745 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1746 4 }
1747 488427721 bool getxdoor_mi(uint mi, uint dir, uint ind)
1748 {
1749
3/6
✓ Branch 0 taken 488427721 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 488427721 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 488427721 times.
488427721 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1750 return false;
1751 488427721 return (game->xdoors[mi][dir] & (1<<ind));
1752 488427721 }
1753 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1754 {
1755 9 int mi = mapind(cur_map, screen);
1756 9 return getxdoor_mi(mi,dir,ind);
1757 }
1758
1759 401 void set_doorstate_mi(uint mi, uint dir)
1760 {
1761
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1762 return;
1763 401 setmapflag_mi(mi, mDOOR_UP << dir);
1764
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1765 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1766 401 }
1767 401 void set_doorstate(uint screen, uint dir)
1768 {
1769 401 int mi = mapind(cur_map, screen);
1770 401 set_doorstate_mi(mi, dir);
1771 401 }
1772
1773 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1774 {
1775
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1776 return;
1777 2 setxdoor_mi(mi, dir, ind, state);
1778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1779 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1780 2 }
1781
1782 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1783 {
1784 2 int mi = mapind(cur_map, screen);
1785 2 set_xdoorstate_mi(mi, dir, ind, state);
1786 2 }
1787
1788 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1789 // returns: -1 = not a warp screen
1790 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1791 {
1792 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1793
1794
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1795 return -1;
1796
1797 57 int32_t ring=scr->catchall;
1798 57 int32_t size=QMisc.warp[ring].size;
1799
1800
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1801 return -2;
1802
1803 57 int32_t index=-1;
1804
1805
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1806
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1807 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1808 57 index=i;
1809
1810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1811 return -3;
1812
1813 57 index = (index+dw)%size;
1814 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1815 57 }
1816
1817 15359888 void update_combo_cycling()
1818 {
1819 15359888 auto& combo_cache = combo_caches::can_cycle;
1820
1821 static int32_t newdata[176];
1822 static int32_t newcset[176];
1823 static bool initialized=false;
1824
1825 // Just a simple bit of optimization
1826
2/2
✓ Branch 0 taken 15359566 times.
✓ Branch 1 taken 322 times.
15359888 if(!initialized)
1827 {
1828
2/2
✓ Branch 0 taken 56672 times.
✓ Branch 1 taken 322 times.
56994 for(int32_t i=0; i<176; i++)
1829 {
1830 56672 newdata[i]=-1;
1831 56672 newcset[i]=-1;
1832 56672 }
1833
1834 322 initialized=true;
1835 322 }
1836
1837 15359888 std::set<uint16_t> restartanim;
1838
1839
1/2
✓ Branch 0 taken 15359888 times.
✗ Branch 1 not taken.
31109144 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1840 15749256 int screen = scr->screen;
1841 int32_t x;
1842
1843
2/2
✓ Branch 0 taken 2771869056 times.
✓ Branch 1 taken 15749256 times.
2787618312 for(int32_t i=0; i<176; i++)
1844 {
1845 2771869056 x=scr->data[i];
1846 2771869056 auto& mini_cmb = combo_cache.minis[x];
1847
2/2
✓ Branch 0 taken 3282224 times.
✓ Branch 1 taken 2768586832 times.
2771869056 if (!mini_cmb.can_cycle)
1848 2768586832 continue;
1849
1850 3282224 newcombo const& cmb = combobuf[x];
1851
1852 //time to restart
1853
4/4
✓ Branch 0 taken 904477 times.
✓ Branch 1 taken 2377747 times.
✓ Branch 2 taken 475770 times.
✓ Branch 3 taken 428707 times.
3282224 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1854 {
1855 428707 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428707 times.
428707 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1857 428707 newdata[i] = c;
1858
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(!(cmb.animflags & AF_CYCLENOCSET))
1859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428687 times.
428687 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1860
1861
2/2
✓ Branch 0 taken 427663 times.
✓ Branch 1 taken 1044 times.
428707 if(combobuf[c].animflags & AF_CYCLE)
1862 {
1863 1044 restartanim.insert(c);
1864 1044 }
1865 428707 }
1866 3282224 }
1867
1868 15749256 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1869
2/2
✓ Branch 0 taken 2771869056 times.
✓ Branch 1 taken 15749256 times.
2787618312 for(int32_t i=0; i<176; i++)
1870 {
1871
2/2
✓ Branch 0 taken 428707 times.
✓ Branch 1 taken 2771440349 times.
2771869056 if(newdata[i]==-1)
1872 2771440349 continue;
1873
1874 428707 rpos_t rpos = (rpos_t)(rpos_base + i);
1875 428707 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1876 428707 screen_combo_modify_preroutine(rpos_handle);
1877 428707 scr->data[i]=newdata[i];
1878
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(newcset[i]>-1)
1879 428687 scr->cset[i]=newcset[i];
1880 428707 screen_combo_modify_postroutine(rpos_handle);
1881
1882 428707 newdata[i]=-1;
1883 428707 newcset[i]=-1;
1884 428707 }
1885
1886 15749256 word c = scr->numFFC();
1887
2/2
✓ Branch 0 taken 15749256 times.
✓ Branch 1 taken 454715631 times.
470464887 for(word i=0; i<c; i++)
1888 {
1889 454715631 ffcdata& ffc = scr->ffcs[i];
1890 454715631 auto& mini_cmb = combo_cache.minis[ffc.data];
1891
2/2
✓ Branch 0 taken 7727 times.
✓ Branch 1 taken 454707904 times.
454715631 if (!mini_cmb.can_cycle)
1892 454707904 continue;
1893
1894 7727 newcombo const& cmb = combobuf[ffc.data];
1895
1896 //time to restart
1897
4/4
✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 6546 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 325 times.
7727 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1898 {
1899 325 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1901 325 zc_ffc_set(ffc, c);
1902
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 108 times.
325 if(!(cmb.animflags & AF_CYCLENOCSET))
1903
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1904
1905
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 60 times.
325 if(combobuf[ffc.data].animflags & AF_CYCLE)
1906 {
1907 60 restartanim.insert(ffc.data);
1908 60 }
1909 325 }
1910 7727 }
1911
1912
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 7330857 times.
15749256 if(get_qr(qr_CMBCYCLELAYERS))
1913 {
1914
2/2
✓ Branch 0 taken 43985142 times.
✓ Branch 1 taken 7330857 times.
51315999 for(int32_t j=1; j<=6; j++)
1915 {
1916 43985142 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1917
2/2
✓ Branch 0 taken 13895276 times.
✓ Branch 1 taken 30089866 times.
43985142 if (!layer_scr)
1918 30089866 continue;
1919
1920
2/2
✓ Branch 0 taken 2445568576 times.
✓ Branch 1 taken 13895276 times.
2459463852 for(int32_t i=0; i<176; i++)
1921 {
1922 2445568576 x=layer_scr->data[i];
1923 2445568576 auto& mini_cmb = combo_cache.minis[x];
1924
2/2
✓ Branch 0 taken 2424344 times.
✓ Branch 1 taken 2443144232 times.
2445568576 if (!mini_cmb.can_cycle)
1925 2443144232 continue;
1926
1927 2424344 newcombo const& cmb = combobuf[x];
1928
1929 //time to restart
1930
4/4
✓ Branch 0 taken 67298 times.
✓ Branch 1 taken 2357046 times.
✓ Branch 2 taken 50626 times.
✓ Branch 3 taken 16672 times.
2424344 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1931 {
1932 16672 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1933
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1934 16672 newdata[i] = c;
1935
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 16028 times.
16672 if(!(cmb.animflags & AF_CYCLENOCSET))
1936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16028 times.
16028 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1937 644 else newcset[i] = layer_scr->cset[i];
1938
1939
2/2
✓ Branch 0 taken 6689 times.
✓ Branch 1 taken 9983 times.
16672 if(combobuf[c].animflags & AF_CYCLE)
1940 {
1941 9983 restartanim.insert(c);
1942 9983 }
1943 16672 }
1944 2424344 }
1945
1946
2/2
✓ Branch 0 taken 2445568576 times.
✓ Branch 1 taken 13895276 times.
2459463852 for (int32_t i=0; i<176; i++)
1947 {
1948
2/2
✓ Branch 0 taken 2445551904 times.
✓ Branch 1 taken 16672 times.
2445568576 if(newdata[i]!=-1)
1949 {
1950 16672 layer_scr->data[i]=newdata[i];
1951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 if(newcset[i]>-1)
1952 16672 layer_scr->cset[i]=newcset[i];
1953 16672 newdata[i]=-1;
1954 16672 newcset[i]=-1;
1955 16672 }
1956 2445568576 }
1957 13895276 }
1958 7330857 }
1959 15749256 });
1960
1961
2/2
✓ Branch 0 taken 15359888 times.
✓ Branch 1 taken 2661 times.
15362549 for (auto i : restartanim)
1962 {
1963 2661 combobuf[i].tile = combobuf[i].o_tile;
1964 2661 combobuf[i].cur_frame=0;
1965 2661 combobuf[i].aclk = 0;
1966
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1967 }
1968 15359888 }
1969
1970 1426210464 bool iswater_type(int32_t type)
1971 {
1972 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1973 1426210464 return (combo_class_buf[type].water!=0);
1974 }
1975
1976 bool iswater(int32_t combo)
1977 {
1978 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1979 }
1980 5280776 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1981 {
1982 5280776 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1983 }
1984
1985 // (x, y) are world coordinates
1986 68242104 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1987 {
1988
8/8
✓ Branch 0 taken 68194241 times.
✓ Branch 1 taken 47863 times.
✓ Branch 2 taken 68152381 times.
✓ Branch 3 taken 41860 times.
✓ Branch 4 taken 68082898 times.
✓ Branch 5 taken 69483 times.
✓ Branch 6 taken 63405 times.
✓ Branch 7 taken 68019493 times.
68242104 if (x<0 || x>=world_w || y<0 || y>=world_h)
1989 222611 return false;
1990
1991 68019493 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
1992 68242104 }
1993
1994 148711462 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1995 {
1996 DCHECK_LAYER_NEG1_INDEX(layer);
1997 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1998 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1999
2000 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2001
2/2
✓ Branch 0 taken 108794353 times.
✓ Branch 1 taken 39917109 times.
148711462 if (get_qr(qr_SMARTER_WATER))
2002 {
2003
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108794353 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108794353 if (DRIEDLAKE) return 0;
2004
5/6
✓ Branch 0 taken 32452247 times.
✓ Branch 1 taken 76342106 times.
✓ Branch 2 taken 6533834 times.
✓ Branch 3 taken 25918413 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6533834 times.
108794353 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2005 {
2006
2/2
✓ Branch 0 taken 75583647 times.
✓ Branch 1 taken 24828400 times.
100412047 for (int32_t m = layer; m <= 1; m++)
2007 {
2008
5/6
✓ Branch 0 taken 49665234 times.
✓ Branch 1 taken 25918413 times.
✓ Branch 2 taken 24835615 times.
✓ Branch 3 taken 24829619 times.
✓ Branch 4 taken 24829619 times.
✗ Branch 5 not taken.
100413266 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2009
1/2
✓ Branch 0 taken 24829619 times.
✗ Branch 1 not taken.
49665234 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2010 {
2011 75583647 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2012
2/2
✓ Branch 0 taken 74493634 times.
✓ Branch 1 taken 1090013 times.
75583647 if (checkwater > 0)
2013 {
2014
2/2
✓ Branch 0 taken 1089930 times.
✓ Branch 1 taken 83 times.
1090013 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2015 1090013 return checkwater;
2016 }
2017 74493634 }
2018 74493634 }
2019 24828400 return 0;
2020 }
2021 else
2022 {
2023
2/2
✓ Branch 0 taken 82899584 times.
✓ Branch 1 taken 78347925 times.
161247509 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2024 {
2025 82899584 int32_t tx2=((i&2)<<2)+x;
2026 82899584 int32_t ty2=((i&1)<<3)+y;
2027 82899584 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2028 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2029
2/2
✓ Branch 0 taken 36073 times.
✓ Branch 1 taken 82863511 times.
82899584 if (!fullcheck)
2030 {
2031 82863511 tx2 = x;
2032 82863511 ty2 = y;
2033
2/2
✓ Branch 0 taken 45332471 times.
✓ Branch 1 taken 37531040 times.
82863511 if(tx2&8) b+=2;
2034
2/2
✓ Branch 0 taken 39268876 times.
✓ Branch 1 taken 43594635 times.
82863511 if(ty2&8) b+=1;
2035 82863511 }
2036
2/2
✓ Branch 0 taken 171770159 times.
✓ Branch 1 taken 80456169 times.
252226328 for (int32_t m = layer; m <= 1; m++)
2037 {
2038 171770159 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2039
3/6
✓ Branch 0 taken 169582656 times.
✓ Branch 1 taken 2187503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169582656 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
171770159 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2040 continue; // dive under this layer
2041
2042
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 154041728 times.
171770159 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2043 {
2044
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17728431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17728431 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2045 {
2046 return 0;
2047 }
2048 17728431 }
2049 else
2050 {
2051
4/4
✓ Branch 0 taken 253102 times.
✓ Branch 1 taken 153788626 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 201950 times.
154041728 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2052 {
2053 201950 return 0;
2054 }
2055 }
2056
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153839778 times.
171568209 if (get_qr(qr_NO_SOLID_SWIM))
2057 {
2058
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 153788626 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2241465 times.
✓ Branch 5 taken 151547161 times.
✓ Branch 6 taken 34499 times.
✓ Branch 7 taken 2206966 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34499 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
153839778 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2059 2241465 return 0;
2060 151598313 }
2061
3/6
✓ Branch 0 taken 497938 times.
✓ Branch 1 taken 168828806 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 497938 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
169326744 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2062 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2063 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2064 {
2065 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2066 }
2067 169326744 }
2068
2069 80456169 bool found_land = false;
2070 80456169 bool found_water = false;
2071 ffc_handle_t water_ffc_handle;
2072 223219866 find_ffc([&](const ffc_handle_t& ffc_handle) {
2073
2/2
✓ Branch 0 taken 141976906 times.
✓ Branch 1 taken 786791 times.
142763697 if (ffcIsAt(ffc_handle, tx2, ty2))
2074 {
2075 786791 auto ty = ffc_handle.ctype();
2076
3/4
✓ Branch 0 taken 786791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 592941 times.
✓ Branch 3 taken 193850 times.
786791 bool is_water_type = combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER);
2077
2078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 786791 times.
786791 if (!is_water_type)
2079 {
2080 786791 found_land = true;
2081 786791 return true;
2082 }
2083 else
2084 {
2085 // A later FFC might be land, in which case the water will be ignored.
2086 if (!found_water)
2087 {
2088 water_ffc_handle = ffc_handle;
2089 found_water = true;
2090 }
2091 }
2092 }
2093
2094 141976906 return false;
2095 142763697 });
2096
2097
2/2
✓ Branch 0 taken 79669378 times.
✓ Branch 1 taken 786791 times.
80456169 if (found_land) return 0;
2098
2099
3/4
✓ Branch 0 taken 79645734 times.
✓ Branch 1 taken 23644 times.
✓ Branch 2 taken 79645734 times.
✗ Branch 3 not taken.
79669378 if (!i && found_water)
2100 {
2101 if (out_handle) *out_handle = water_ffc_handle;
2102 return water_ffc_handle.data();
2103 }
2104
2105 79669378 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2106
2/2
✓ Branch 0 taken 79624884 times.
✓ Branch 1 taken 44494 times.
79669378 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2107
7/12
✓ Branch 0 taken 79194862 times.
✓ Branch 1 taken 430022 times.
✓ Branch 2 taken 17017684 times.
✓ Branch 3 taken 62177178 times.
✓ Branch 4 taken 16192814 times.
✓ Branch 5 taken 824870 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16192814 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
79624884 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2108 {
2109
2/2
✓ Branch 0 taken 1577 times.
✓ Branch 1 taken 1253315 times.
1254892 if (i == 0)
2110 {
2111
2/2
✓ Branch 0 taken 1253306 times.
✓ Branch 1 taken 9 times.
1253315 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2112 1253315 return checkcombo;
2113 }
2114 1577 }
2115 78371569 }
2116 78347925 return 0;
2117 }
2118 }
2119 else
2120 {
2121 39917109 int32_t b = 0;
2122
2/2
✓ Branch 0 taken 20704060 times.
✓ Branch 1 taken 19213049 times.
39917109 if(x&8) b+=2;
2123
2/2
✓ Branch 0 taken 15524133 times.
✓ Branch 1 taken 24392976 times.
39917109 if(y&8) b+=1;
2124
1/2
✓ Branch 0 taken 39917109 times.
✗ Branch 1 not taken.
39917109 if (get_qr(qr_NO_SOLID_SWIM))
2125 {
2126 if (combobuf[combo].walk&(1<<b))
2127 {
2128 return 0;
2129 }
2130 }
2131
1/2
✓ Branch 0 taken 39917109 times.
✗ Branch 1 not taken.
39917109 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2132
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1766208 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1778552 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 165477 times.
39917109 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2133 {
2134
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2135 1944029 return combo;
2136 }
2137 38146730 return 0;
2138 }
2139 148885112 }
2140
2141 354 bool isdamage_type(int32_t type)
2142 {
2143
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 28 times.
354 switch(type)
2144 {
2145 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2146 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2147 28 return true;
2148 }
2149 326 return false;
2150 354 }
2151
2152 2230890586 bool ispitfall_type(int32_t type)
2153 {
2154 2230890586 return combo_class_buf[type].pit != 0;
2155 }
2156
2157 2230890586 bool ispitfall(int32_t combo)
2158 {
2159 2230890586 return ispitfall_type(combobuf[combo].type);
2160 }
2161
2162 138854937 bool ispitfall(int32_t x, int32_t y)
2163 {
2164
2/2
✓ Branch 0 taken 1303540 times.
✓ Branch 1 taken 137551397 times.
138854937 if(int32_t c = MAPFFCOMBO(x,y))
2165 {
2166 1303540 return ispitfall(c) ? true : false;
2167 }
2168 137551397 int32_t c = MAPCOMBOL(2,x,y);
2169
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 137551320 times.
137551397 if(ispitfall(c)) return true;
2170
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14894877 times.
137551320 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2171 {
2172
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2173 122656443 }
2174 else
2175 {
2176
3/4
✓ Branch 0 taken 16383 times.
✓ Branch 1 taken 14878494 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16383 times.
14894877 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2177 }
2178 137534937 c = MAPCOMBOL(1,x,y);
2179
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 137514969 times.
137534937 if(ispitfall(c)) return true;
2180
2181
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14858526 times.
137514969 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2182 {
2183
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2184 122656443 }
2185 else
2186 {
2187
4/4
✓ Branch 0 taken 16533 times.
✓ Branch 1 taken 14841993 times.
✓ Branch 2 taken 12238 times.
✓ Branch 3 taken 4295 times.
14858526 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2188 }
2189 137502731 c = MAPCOMBO(x,y);
2190
2/2
✓ Branch 0 taken 59028 times.
✓ Branch 1 taken 137443703 times.
137502731 if(ispitfall(c)) return true;
2191 137443703 return false;
2192 138854937 }
2193
2194 612096745 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2195 {
2196
2/2
✓ Branch 0 taken 9485176 times.
✓ Branch 1 taken 602611569 times.
612096745 if(int32_t c = MAPFFCOMBO(x,y))
2197 {
2198
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 9484331 times.
9485176 return ispitfall(c) ? c : 0;
2199 }
2200 602611569 int32_t c = MAPCOMBOL(2,x,y);
2201
2/2
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 602610207 times.
602611569 if(ispitfall(c)) return c;
2202
2203
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69887722 times.
602610207 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2204 {
2205
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2206 532722485 }
2207 else
2208 {
2209
3/4
✓ Branch 0 taken 81755 times.
✓ Branch 1 taken 69805967 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81755 times.
69887722 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2210 }
2211 602528452 c = MAPCOMBOL(1,x,y);
2212
2/2
✓ Branch 0 taken 25192 times.
✓ Branch 1 taken 602503260 times.
602528452 if(ispitfall(c)) return c;
2213
2214
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69780775 times.
602503260 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2215 {
2216
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2217 532722485 }
2218 else
2219 {
2220
4/4
✓ Branch 0 taken 171385 times.
✓ Branch 1 taken 69609390 times.
✓ Branch 2 taken 130757 times.
✓ Branch 3 taken 40628 times.
69780775 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2221 }
2222 602372503 c = MAPCOMBO(x,y);
2223
2/2
✓ Branch 0 taken 200737 times.
✓ Branch 1 taken 602171766 times.
602372503 if(ispitfall(c)) return c;
2224 602171766 return 0;
2225 612096745 }
2226 99 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2227 {
2228
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 98 times.
99 if(int32_t c = MAPFFCOMBO(x,y))
2229 {
2230
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2231 }
2232 98 int32_t c = MAPCOMBOL(2,x,y);
2233
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 97 times.
98 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2234
2235
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 91 times.
97 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2236 {
2237
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2238 return nullopt;
2239 6 }
2240 else
2241 {
2242
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
91 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2243 return nullopt;
2244 }
2245 97 c = MAPCOMBOL(1,x,y);
2246
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2247
2248
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 79 times.
85 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2249 {
2250
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2251 return nullopt;
2252 6 }
2253 else
2254 {
2255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
79 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2256 return nullopt;
2257 }
2258 85 c = MAPCOMBO(x,y);
2259
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2260 return nullopt;
2261 99 }
2262 11918937 bool check_icy(newcombo const& cmb, int type)
2263 {
2264
2/2
✓ Branch 0 taken 11918772 times.
✓ Branch 1 taken 165 times.
11918937 if(cmb.type != cICY)
2265 11918772 return false;
2266
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2267 {
2268 case ICY_BLOCK:
2269 return cmb.usrflags&cflag1;
2270 case ICY_PLAYER:
2271 165 return cmb.usrflags&cflag2;
2272 }
2273 return false;
2274 11918937 }
2275 3978929 int get_icy(int x, int y, int type)
2276 {
2277 3978929 int32_t c = MAPCOMBOL(2,x,y);
2278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3978929 times.
3978929 if(check_icy(combobuf[c], type)) return c;
2279
2280 3978929 int screen = get_screen_for_world_xy(x, y);
2281
2282 3978929 mapscr* scr = get_scr_layer_valid(screen, 2);
2283
2/2
✓ Branch 0 taken 33173 times.
✓ Branch 1 taken 3945756 times.
3978929 if (scr)
2284 {
2285
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 3945240 times.
3945756 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2286 {
2287
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2288 516 }
2289 else
2290 {
2291
3/4
✓ Branch 0 taken 6663 times.
✓ Branch 1 taken 3938577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6663 times.
3945240 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2292 }
2293 3939093 }
2294 3972266 c = MAPCOMBOL(1,x,y);
2295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3972266 times.
3972266 if(check_icy(combobuf[c], type)) return c;
2296
2297 3972266 scr = get_scr_layer_valid(screen, 1);
2298
2/2
✓ Branch 0 taken 15312 times.
✓ Branch 1 taken 3956954 times.
3972266 if (scr)
2299 {
2300
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 3955020 times.
3956954 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2301 {
2302
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2303 1934 }
2304 else
2305 {
2306
3/4
✓ Branch 0 taken 4689 times.
✓ Branch 1 taken 3950331 times.
✓ Branch 2 taken 4689 times.
✗ Branch 3 not taken.
3955020 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2307 }
2308 3952265 }
2309 3967577 c = MAPCOMBO(x,y);
2310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3967577 times.
3967577 if(check_icy(combobuf[c], type)) return c;
2311 3967577 return 0;
2312 3978929 }
2313
2314 13261299 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2315 {
2316
8/8
✓ Branch 0 taken 13254501 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13245635 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13234003 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 434748 times.
✓ Branch 7 taken 12799255 times.
13261299 if(x<0 || x>=world_w || y<0 || y>=world_h)
2317 462044 return false;
2318
2319 12799255 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2320
2/4
✓ Branch 0 taken 12799255 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12799255 times.
12799255 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2321 return true;
2322
2323 12799255 change_rpos_handle_layer(rpos_handle, 1);
2324
2/2
✓ Branch 0 taken 7571606 times.
✓ Branch 1 taken 5227649 times.
12799255 if (rpos_handle.scr->is_valid())
2325
3/4
✓ Branch 0 taken 5227649 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5224370 times.
5227649 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2326 3279 return true;
2327
2328 12795976 change_rpos_handle_layer(rpos_handle, 2);
2329
2/2
✓ Branch 0 taken 10855408 times.
✓ Branch 1 taken 1940568 times.
12795976 if (rpos_handle.scr->is_valid())
2330
3/4
✓ Branch 0 taken 1940568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 1940487 times.
1940568 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2331 81 return true;
2332
2333 12795895 return false;
2334 13261299 }
2335
2336 6694832 bool isSVLadder(int32_t x, int32_t y)
2337 {
2338 6694832 return checkSV(x, y, mfSIDEVIEWLADDER);
2339 }
2340
2341 6566467 bool isSVPlatform(int32_t x, int32_t y)
2342 {
2343 6566467 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2344 }
2345
2346 6566467 bool checkSVLadderPlatform(int32_t x, int32_t y)
2347 {
2348
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6566467 times.
✓ Branch 2 taken 6564629 times.
✓ Branch 3 taken 1838 times.
6566467 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2349 }
2350
2351 4206 bool isstepable(int32_t combo) //can use ladder on it
2352 {
2353
2/2
✓ Branch 0 taken 4200 times.
✓ Branch 1 taken 6 times.
4206 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2354
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2355 {
2356 if(combobuf[combo].usrflags&cflag4)
2357 {
2358 int32_t ldrid = current_item_id(itype_ladder);
2359 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2360 }
2361 }
2362 6 return false;
2363 4206 }
2364
2365 33016 bool isHSGrabbable(newcombo const& cmb)
2366 {
2367
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 32639 times.
33016 if(cmb.type == cHSGRAB) return true;
2368 32639 return cmb.genflags & cflag1;
2369 33016 }
2370
2371 954 bool isSwitchHookable(newcombo const& cmb)
2372 {
2373
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2374 822 return cmb.genflags & cflag2;
2375 954 }
2376
2377 62207 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2378 {
2379 62207 rpos_t cpos = rpos_t::None;
2380
2/2
✓ Branch 0 taken 65056 times.
✓ Branch 1 taken 127263 times.
62207 if(out_rpos)
2381 {
2382 127263 int32_t id = MAPCOMBO2(layer-1,x,y);
2383
2/2
✓ Branch 0 taken 29204 times.
✓ Branch 1 taken 98059 times.
127263 if(id > 0)
2384 {
2385 98059 newcombo const& cmb = combobuf[id];
2386
4/4
✓ Branch 0 taken 32974 times.
✓ Branch 1 taken 65085 times.
✓ Branch 2 taken 32528 times.
✓ Branch 3 taken 32557 times.
98059 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2387 33003 }
2388 62207 }
2389
2390 127263 ffcdata* ffc = nullptr;
2391
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3535 times.
127263 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2392 {
2393 10645 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2394
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 115 times.
7110 if (ffcIsAt(ffc_handle, x, y))
2395 {
2396 115 auto& cmb = ffc_handle.combo();
2397
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2398 {
2399 79 ffc = ffc_handle.ffc;
2400 79 return false;
2401 }
2402 36 }
2403 7031 return true;
2404 7038 });
2405 3535 }
2406
2407
4/4
✓ Branch 0 taken 62207 times.
✓ Branch 1 taken 65056 times.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 61761 times.
127263 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2408
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28524 times.
127263 if (out_ffc && ffc) *out_ffc = ffc;
2409
2/2
✓ Branch 0 taken 65502 times.
✓ Branch 1 taken 61761 times.
127263 return (cpos != rpos_t::None || ffc);
2410 }
2411
2412 5199 bool ishookshottable(int32_t bx, int32_t by)
2413 {
2414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5199 times.
5199 if(!_walkflag(bx,by,1))
2415 return true;
2416
2417
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5191 times.
5199 if (collide_object(bx, by, 1, 1))
2418 8 return false;
2419
2420 5191 bool ret = true;
2421
2/2
✓ Branch 0 taken 15573 times.
✓ Branch 1 taken 1904 times.
17477 for(int32_t i=2; i>=0; i--)
2422 {
2423 15573 int32_t c = MAPCOMBO2(i-1,bx,by);
2424 15573 int32_t t = combobuf[c].type;
2425
2426
6/6
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 10382 times.
✓ Branch 2 taken 3857 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1904 times.
✓ Branch 5 taken 1953 times.
15573 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2427
2428
3/4
✓ Branch 0 taken 11333 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13239 bool dried = (iswater_type(t) && DRIEDLAKE);
2429
2430 12286 int32_t b=1;
2431
2432
2/2
✓ Branch 0 taken 6112 times.
✓ Branch 1 taken 6174 times.
12286 if(bx&8) b<<=2;
2433
2434
2/2
✓ Branch 0 taken 3853 times.
✓ Branch 1 taken 8433 times.
12286 if(by&8) b<<=1;
2435
2436
7/8
✓ Branch 0 taken 2098 times.
✓ Branch 1 taken 10188 times.
✓ Branch 2 taken 2098 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 983 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 908 times.
12286 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2437 908 ret = false;
2438 12286 }
2439
2440 1904 return ret;
2441 5199 }
2442
2443 11108 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2444 {
2445
4/4
✓ Branch 0 taken 10529 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 10529 times.
✓ Branch 3 taken 579 times.
11108 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2446 {
2447 579 int pos = COMBOPOS(s->stairx,s->stairy);
2448 579 s->data[pos] = s->secretcombo[sSTAIRS];
2449 579 s->cset[pos] = s->secretcset[sSTAIRS];
2450 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2451
2452
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2453 {
2454 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2455 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2456 256 }
2457
2458 579 return true;
2459 }
2460
2461 10529 return false;
2462 11108 }
2463
2464 52908 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2465 {
2466 DCHECK(base_scr->is_valid());
2467
2468 52908 screen_handles_t screen_handles{};
2469 52908 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2470 52908 return screen_handles;
2471 }
2472
2473 58579548 screen_handles_t create_screen_handles(mapscr* base_scr)
2474 {
2475 DCHECK(get_scr(base_scr->screen) == base_scr);
2476 DCHECK(base_scr->is_valid());
2477
2478 58579548 int screen = base_scr->screen;
2479 screen_handles_t screen_handles;
2480 58579548 screen_handles[0] = {base_scr, base_scr, screen, 0};
2481
2/2
✓ Branch 0 taken 351477288 times.
✓ Branch 1 taken 58579548 times.
410056836 for (int i = 1; i <= 6; i++)
2482 351477288 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2483 58579548 return screen_handles;
2484 }
2485
2486 113471 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2487 {
2488 113471 mapscr* scr = screen_handles[0].scr;
2489 113471 bool didit=false;
2490
2491
2/2
✓ Branch 0 taken 113471 times.
✓ Branch 1 taken 19970896 times.
20084367 for(int32_t i=0; i<176; i++)
2492 {
2493 19970896 newcombo const& cmb = combobuf[scr->data[i]];
2494
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19970570 times.
19970896 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2495
4/4
✓ Branch 0 taken 19968994 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 19967860 times.
19970570 if((cmb.type == what1) || (cmb.type== what2))
2496 {
2497 2710 scr->data[i]++;
2498 2710 didit=true;
2499 2710 }
2500 19970570 }
2501
2502
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 113379 times.
113471 if (do_layers)
2503 {
2504
2/2
✓ Branch 0 taken 680274 times.
✓ Branch 1 taken 113379 times.
793653 for(int32_t j=1; j<=6; j++)
2505 {
2506 680274 mapscr* layer_scr = screen_handles[j].scr;
2507
2/2
✓ Branch 0 taken 195881 times.
✓ Branch 1 taken 484393 times.
680274 if (!layer_scr) continue;
2508
2509
2/2
✓ Branch 0 taken 34475056 times.
✓ Branch 1 taken 195881 times.
34670937 for(int32_t i=0; i<176; i++)
2510 {
2511 34475056 newcombo const& cmb = combobuf[layer_scr->data[i]];
2512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34475056 times.
34475056 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2513
4/4
✓ Branch 0 taken 34474741 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 34474422 times.
34475056 if((cmb.type== what1) || (cmb.type== what2))
2514 {
2515 634 layer_scr->data[i]++;
2516 634 didit=true;
2517 634 }
2518 34475056 }
2519 195881 }
2520 113379 }
2521
2522 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2523
3/4
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27675 times.
113471 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2524 {
2525 27675 word c = scr->numFFC();
2526
2/2
✓ Branch 0 taken 80883 times.
✓ Branch 1 taken 27675 times.
108558 for(word i=0; i<c; i++)
2527 {
2528 80883 ffcdata* ffc = &scr->ffcs[i];
2529 80883 newcombo const& cmb = combobuf[ffc->data];
2530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80883 times.
80883 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2531
2/4
✓ Branch 0 taken 80883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80883 times.
80883 if((cmb.type== what1) || (cmb.type== what2))
2532 {
2533 zc_ffc_modify(*ffc, 1);
2534 didit=true;
2535 }
2536 80883 }
2537 27675 }
2538
2539 113471 return didit;
2540 }
2541
2542 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2543 {
2544 14 int screen = screen_handles[0].scr->screen;
2545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2546 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2547 }
2548 488427726 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2549 {
2550 488427726 bool didit=false;
2551
2/2
✓ Branch 0 taken 488386765 times.
✓ Branch 1 taken 40961 times.
488427726 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2552
2553 40961 mapscr* s = screen_handles[0].scr;
2554 40961 int screen = s->screen;
2555 40961 bool is_active_screen = is_in_current_region(s);
2556
2557 34122305 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2558
4/4
✓ Branch 0 taken 49456 times.
✓ Branch 1 taken 34031888 times.
✓ Branch 2 taken 1891 times.
✓ Branch 3 taken 34079453 times.
34081344 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2559 1891 didit = true;
2560
2/2
✓ Branch 0 taken 64673 times.
✓ Branch 1 taken 34014780 times.
34079453 else switch (rpos_handle.ctype())
2561 {
2562 case cLOCKBLOCK: case cLOCKBLOCK2:
2563 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2564 case cCHEST: case cCHEST2:
2565 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2566 case cBOSSCHEST: case cBOSSCHEST2:
2567 {
2568 64673 auto& cmb = rpos_handle.combo();
2569
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 2614 times.
64673 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2570
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2571 {
2572 29 rpos_handle.increment_data();
2573 29 didit=true;
2574 29 }
2575 62059 break;
2576 }
2577 }
2578 34081344 });
2579
2580
4/4
✓ Branch 0 taken 40889 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 31269 times.
✓ Branch 3 taken 9620 times.
40961 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2581 {
2582 31269 word c = s->numFFC();
2583 31269 int screen_index_offset = get_region_screen_offset(screen);
2584
2/2
✓ Branch 0 taken 65746 times.
✓ Branch 1 taken 31269 times.
97015 for (uint8_t i = 0; i < c; i++)
2585 {
2586 65746 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2587 65746 auto& cmb = ffc_handle.combo();
2588
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 65746 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 65730 times.
65746 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2589 16 didit = true;
2590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65730 times.
65730 else switch(cmb.type)
2591 {
2592 case cLOCKBLOCK: case cLOCKBLOCK2:
2593 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2594 case cCHEST: case cCHEST2:
2595 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2596 case cBOSSCHEST: case cBOSSCHEST2:
2597 {
2598 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2599 if(cmb.attribytes[5] == xflag)
2600 {
2601 zc_ffc_modify(*ffc_handle.ffc, 1);
2602 didit=true;
2603 }
2604 break;
2605 }
2606 }
2607 65746 }
2608 31269 }
2609
2610 40961 return didit;
2611 488427726 }
2612
2613 15210235 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2614 {
2615 15210235 int screen = screen_handles[0].screen;
2616
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14822402 times.
15210235 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2617 15210235 clear_xstatecombos_mi(screen_handles, mi, triggers);
2618 15210235 }
2619
2620 15263366 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2621 {
2622
2/2
✓ Branch 0 taken 488427712 times.
✓ Branch 1 taken 15263366 times.
503691078 for (int q = 0; q < 32; ++q)
2623 {
2624 488427712 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2625 488427712 }
2626 15263366 }
2627
2628 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2629 {
2630 int screen = screen_handles[0].screen;
2631 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2632 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2633 }
2634 488427712 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2635 {
2636 488427712 bool didit=false;
2637
2/2
✓ Branch 0 taken 488426399 times.
✓ Branch 1 taken 1313 times.
488427712 if (!getxdoor_mi(mi, dir, ind)) return false;
2638
2639 1313 mapscr* scr = screen_handles[0].scr;
2640 1313 int screen = scr->screen;
2641 1313 bool is_active_screen = is_in_current_region(scr);
2642
2643 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2644
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2645 11 didit = true;
2646 else; //future door combo types?
2647 924352 });
2648
2649
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2650 {
2651 1313 word c = scr->numFFC();
2652 1313 int screen_index_offset = get_region_screen_offset(screen);
2653
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2654 {
2655 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2656 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2657 didit = true;
2658 else; //future door combo types?
2659 }
2660 1313 }
2661
2662 1313 return didit;
2663 488427712 }
2664
2665 15210235 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2666 {
2667 15210235 int screen = screen_handles[0].screen;
2668
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14822402 times.
15210235 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2669 15210235 return clear_xdoors_mi(screen_handles, mi, triggers);
2670 }
2671
2672 15263366 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2673 {
2674
2/2
✓ Branch 0 taken 61053464 times.
✓ Branch 1 taken 15263366 times.
76316830 for (int dir = 0; dir < 4; ++dir)
2675
2/2
✓ Branch 0 taken 488427712 times.
✓ Branch 1 taken 61053464 times.
549481176 for (int q = 0; q < 8; ++q)
2676 549481176 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2677 15263366 }
2678
2679 885 bool remove_lockblocks(const screen_handles_t& screen_handles)
2680 {
2681 885 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2682 }
2683
2684 139 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2685 {
2686 139 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2687 }
2688
2689 83659 bool remove_chests(const screen_handles_t& screen_handles)
2690 {
2691 83659 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2692 }
2693
2694 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2695 {
2696 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2697 }
2698
2699 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2700 {
2701 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2702 }
2703
2704 1418795 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2705 {
2706 1418795 int32_t ct=rpos_handle.ctype();
2707
2708
6/6
✓ Branch 0 taken 1418175 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1417923 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1417815 times.
✓ Branch 5 taken 108 times.
1418795 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2709 1417815 return;
2710
2711 2465 auto [cx, cy] = rpos_handle.xy();
2712
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2713 {
2714 case cL_STATUE:
2715 620 cx += 4;
2716 620 cy += 7;
2717 620 break;
2718
2719 case cR_STATUE:
2720 252 cx -= 8;
2721 252 cy -= 1;
2722 252 break;
2723
2724 case cC_STATUE:
2725 108 break;
2726 }
2727
2728
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2729 {
2730 // Finds the smallest enemy ID
2731
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 346 times.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2732 {
2733 346 guys.del(j);
2734 346 }
2735 1485 }
2736 1418795 }
2737
2738 45 static int32_t findtrigger(int32_t screen)
2739 {
2740 45 int32_t checkflag=0;
2741 45 int32_t ret = 0;
2742
2743 mapscr* screens[7];
2744
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 45 times.
360 for (int32_t j = 0; j <= 6; j++)
2745 {
2746 315 screens[j] = get_scr_layer_valid(screen, j);
2747 315 }
2748
2749 45 bool sflag = false;
2750
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 45 times.
7965 for(word j=0; j<176; j++)
2751 {
2752
2/2
✓ Branch 0 taken 87648 times.
✓ Branch 1 taken 7920 times.
95568 for(int32_t layer = -1; layer < 6; ++layer)
2753 {
2754 87648 mapscr* scr = screens[layer+1];
2755
2/2
✓ Branch 0 taken 64416 times.
✓ Branch 1 taken 23232 times.
87648 if (!scr) continue;
2756
2757
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if(sflag)
2758 32208 checkflag = scr->sflag[j];
2759 else
2760 32208 checkflag = combobuf[scr->data[j]].flag;
2761 64416 sflag = !sflag;
2762
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if (sflag) --layer;
2763
2764
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 64374 times.
64416 switch(checkflag)
2765 {
2766 case mfANYFIRE:
2767 case mfSTRONGFIRE:
2768 case mfMAGICFIRE:
2769 case mfDIVINEFIRE:
2770 case mfARROW:
2771 case mfSARROW:
2772 case mfGARROW:
2773 case mfSBOMB:
2774 case mfBOMB:
2775 case mfBRANG:
2776 case mfMBRANG:
2777 case mfFBRANG:
2778 case mfWANDMAGIC:
2779 case mfREFMAGIC:
2780 case mfREFFIREBALL:
2781 case mfSWORD:
2782 case mfWSWORD:
2783 case mfMSWORD:
2784 case mfXSWORD:
2785 case mfSWORDBEAM:
2786 case mfWSWORDBEAM:
2787 case mfMSWORDBEAM:
2788 case mfXSWORDBEAM:
2789 case mfHOOKSHOT:
2790 case mfWAND:
2791 case mfHAMMER:
2792 case mfSTRIKE:
2793 42 ret += 1;
2794 42 break;
2795 }
2796 64416 }
2797 7920 }
2798
2799 45 return ret;
2800 }
2801
2802 12340 static void log_trigger_secret_reason(TriggerSource source)
2803 {
2804
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11888 times.
12340 if (source == TriggerSource::Singular)
2805 {
2806 452 Z_eventlog("Restricted Screen Secrets triggered\n");
2807 452 }
2808 else
2809 {
2810 11888 const char* source_str = "";
2811
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7297 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 3114 times.
✓ Branch 5 taken 500 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 75 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11888 switch (source)
2812 {
2813 case TriggerSource::Singular: break;
2814 7297 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2815 897 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2816 3114 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2817 500 case TriggerSource::Script: source_str = "a script"; break;
2818 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2819 75 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2820 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2821 case TriggerSource::SCC: source_str = "SCC"; break;
2822 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2823 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2824 }
2825 11888 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2826 }
2827 12340 }
2828
2829 // single:
2830 // >-1 : the singular triggering combo
2831 // -1: triggered by some other cause
2832 12132 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2833 {
2834 12132 log_trigger_secret_reason(source);
2835
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single < 0)
2836 11680 get_screen_state(scr->screen).triggered_secrets = true;
2837
2838 12132 bool do_replay_comment = true;
2839 12132 bool from_active_screen = true;
2840 12132 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2841
2842 // Respect secret state carryovers for active screens.
2843
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single >= 0) return;
2844
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 11655 times.
11680 if(scr->nocarry&mSECRET) return;
2845 11655 int cmap = scr->map;
2846 11655 int cscr = scr->screen;
2847 11655 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2848 11655 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2849
2850 11655 std::vector<int32_t> done;
2851
2/2
✓ Branch 0 taken 11450 times.
✓ Branch 1 taken 205 times.
11655 bool looped = (nmap==cmap+1 && nscr==cscr);
2852
2853
6/6
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 11569 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 11655 times.
12155 while((nmap!=0) && !looped && !(nscr>=128))
2854 {
2855
7/8
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 295 times.
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 89 times.
500 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2856 {
2857
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2858
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2859
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2860 4 }
2861
2862 500 cmap=nmap;
2863 500 cscr=nscr;
2864 500 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2865 500 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2866
2867
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 500 times.
943 for(auto it = done.begin(); it != done.end(); it++)
2868 {
2869
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 86 times.
443 if(*it == ((nmap-1)<<7)+nscr)
2870 86 looped = true;
2871 443 }
2872
2873
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 done.push_back(((nmap-1)<<7)+nscr);
2874 }
2875 12132 }
2876
2877 2550 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2878 {
2879 2550 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2880 2550 }
2881
2882 19223 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2883 {
2884 19223 mapscr* scr = screen_handles[0].scr;
2885 19223 int screen = scr->screen;
2886
2887 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2888 // slopes in sideview mode (which required loading nearby screens in loadscr).
2889 // TODO(replays): This should just use `screen`.
2890
3/4
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 18684 times.
19223 if (replay_is_active() && do_replay_comment)
2891
4/6
✓ Branch 0 taken 12136 times.
✓ Branch 1 taken 6548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12136 times.
✓ Branch 4 taken 18684 times.
✗ Branch 5 not taken.
18684 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2892
2893
2/2
✓ Branch 0 taken 7087 times.
✓ Branch 1 taken 12136 times.
19223 if (from_active_screen)
2894 {
2895 6099822 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2896
2/4
✓ Branch 0 taken 6085024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2662 times.
✗ Branch 3 not taken.
6407603 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2897 319917 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2898 }, ctrigSECRETS);
2899 6087686 });
2900 12136 }
2901
2902 19223 int32_t ft=0; //Flag trigger?
2903 19223 int32_t msflag=0; // Misc. secret flag
2904
2905
2/2
✓ Branch 0 taken 3383248 times.
✓ Branch 1 taken 19223 times.
3402471 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2906 {
2907
4/4
✓ Branch 0 taken 79552 times.
✓ Branch 1 taken 3303696 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 79100 times.
3383248 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2908
2909 // Remember the misc. secret flag; if triggered, use this instead
2910
4/4
✓ Branch 0 taken 153551 times.
✓ Branch 1 taken 3150597 times.
✓ Branch 2 taken 87558 times.
✓ Branch 3 taken 65993 times.
3304148 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2911 65993 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2912
4/4
✓ Branch 0 taken 47862 times.
✓ Branch 1 taken 3190293 times.
✓ Branch 2 taken 47336 times.
✓ Branch 3 taken 526 times.
3238155 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2913 526 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2914 else
2915 3237629 msflag=0;
2916
2917
4/4
✓ Branch 0 taken 922853 times.
✓ Branch 1 taken 2381295 times.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 922768 times.
3304148 if(!high16only || single>=0)
2918 {
2919 2381380 int32_t newflag = -1;
2920
2921
2/2
✓ Branch 0 taken 4762760 times.
✓ Branch 1 taken 2381380 times.
7144140 for(int32_t iter=0; iter<2; ++iter)
2922 {
2923 4762760 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2924
2925
2/2
✓ Branch 0 taken 2381380 times.
✓ Branch 1 taken 2381380 times.
4762760 if(iter==1) checkflag=scr->sflag[i]; //Placed
2926
2927 4762760 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2928
2/2
✓ Branch 0 taken 4750287 times.
✓ Branch 1 taken 12473 times.
4762760 if (ft != -1) //Change the combos for the secret
2929 {
2930 // Use misc. secret flag instead if one is present
2931
2/2
✓ Branch 0 taken 12441 times.
✓ Branch 1 taken 32 times.
12473 if(msflag!=0)
2932 32 ft=msflag;
2933
2934 12473 rpos_handle_t rpos_handle;
2935
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2936 {
2937 5932 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2938 5932 screen_combo_modify_preroutine(rpos_handle);
2939 5932 }
2940
2941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12473 times.
12473 if(ft==sSECNEXT)
2942 {
2943 scr->data[i]++;
2944 }
2945 else
2946 {
2947 12473 scr->data[i] = scr->secretcombo[ft];
2948 12473 scr->cset[i] = scr->secretcset[ft];
2949 }
2950 12473 newflag = scr->secretflag[ft];
2951
2952
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2953 5932 screen_combo_modify_postroutine(rpos_handle);
2954 12473 }
2955 4762760 }
2956
2957
2/2
✓ Branch 0 taken 2368913 times.
✓ Branch 1 taken 12467 times.
2381380 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2958
2959
2/2
✓ Branch 0 taken 14288280 times.
✓ Branch 1 taken 2381380 times.
16669660 for(int32_t j=1; j<=6; j++) //Layers
2960 {
2961 14288280 mapscr* layer_scr = screen_handles[j].scr;
2962
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 9987302 times.
14288280 if (!layer_scr) continue;
2963
2964
3/4
✓ Branch 0 taken 770 times.
✓ Branch 1 taken 4300208 times.
✓ Branch 2 taken 770 times.
✗ Branch 3 not taken.
4300978 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2965
2966 4300978 int32_t newflag2 = -1;
2967
2968 // Remember the misc. secret flag; if triggered, use this instead
2969
4/4
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 4282910 times.
✓ Branch 2 taken 6284 times.
✓ Branch 3 taken 11784 times.
4300978 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2970 11784 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2971
4/4
✓ Branch 0 taken 132026 times.
✓ Branch 1 taken 4157168 times.
✓ Branch 2 taken 130774 times.
✓ Branch 3 taken 1252 times.
4289194 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2972 1252 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2973 else
2974 4287942 msflag=0;
2975
2976
2/2
✓ Branch 0 taken 8601956 times.
✓ Branch 1 taken 4300978 times.
12902934 for(int32_t iter=0; iter<2; ++iter)
2977 {
2978 8601956 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2979
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 4300978 times.
8601956 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2980
2981 8601956 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2982
2/2
✓ Branch 0 taken 8600177 times.
✓ Branch 1 taken 1779 times.
8601956 if (ft != -1) //Change the combos for the secret
2983 {
2984 // Use misc. secret flag instead if one is present
2985
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 2 times.
1779 if(msflag!=0)
2986 2 ft=msflag;
2987
2988
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1779 times.
1779 if(ft==sSECNEXT)
2989 {
2990 layer_scr->data[i]++;
2991 }
2992 else
2993 {
2994 1779 layer_scr->data[i] = layer_scr->secretcombo[ft];
2995 1779 layer_scr->cset[i] = layer_scr->secretcset[ft];
2996 }
2997 1779 newflag2 = layer_scr->secretflag[ft];
2998 1779 int32_t c=layer_scr->data[i];
2999 1779 int32_t cs=layer_scr->cset[i];
3000
3001
3/4
✓ Branch 0 taken 908 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 908 times.
✗ Branch 3 not taken.
1779 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3002 {
3003 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3004 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3005 }
3006 1779 }
3007 8601956 }
3008
3009
2/2
✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 4299212 times.
4300978 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3010 4300978 }
3011 2381380 }
3012 3304148 }
3013
3014 19223 word c = scr->numFFC();
3015
2/2
✓ Branch 0 taken 508334 times.
✓ Branch 1 taken 19223 times.
527557 for(word i=0; i<c; i++) //FFC 'trigger flags'
3016 {
3017
3/4
✓ Branch 0 taken 494280 times.
✓ Branch 1 taken 14054 times.
✓ Branch 2 taken 14054 times.
✗ Branch 3 not taken.
508334 if(single>=0) if(i+176!=single) continue;
3018
3019
3/4
✓ Branch 0 taken 166649 times.
✓ Branch 1 taken 327631 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166649 times.
494280 if((!high16only)||(single>=0))
3020 {
3021 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3022 {
3023 327631 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3024 //No placed flags yet
3025
3026 327631 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3027
2/2
✓ Branch 0 taken 327600 times.
✓ Branch 1 taken 31 times.
327631 if (ft != -1) //Change the ffc's combo
3028 {
3029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3030 {
3031 zc_ffc_modify(scr->ffcs[i], 1);
3032 }
3033 else
3034 {
3035 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3036 31 scr->ffcs[i].cset = scr->secretcset[ft];
3037 }
3038 31 }
3039 }
3040 327631 }
3041 494280 }
3042
3043
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 2498 times.
19223 if(checktrigger) //Hit all triggers->16-31
3044 {
3045 2498 checktrigger=false;
3046
3047
2/2
✓ Branch 0 taken 2474 times.
✓ Branch 1 taken 24 times.
2498 if(scr->flags6&fTRIGGERF1631)
3048 {
3049 24 int32_t tr = findtrigger(screen); //Normal flags
3050
3051
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 if(tr)
3052 {
3053 14 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3054 14 goto endhe;
3055 }
3056 10 }
3057 2484 }
3058
3059
2/2
✓ Branch 0 taken 3380784 times.
✓ Branch 1 taken 19209 times.
3399993 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3060 {
3061 //If it's an enemies->secret screen, only do the high 16 if told to
3062 //That way you can have secret and burn/bomb entrance separately
3063 3380784 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3064
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 600160 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3295600 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3380784 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3065 {
3066 3315136 int32_t newflag = -1;
3067
3068
2/2
✓ Branch 0 taken 6630272 times.
✓ Branch 1 taken 3315136 times.
9945408 for(int32_t iter=0; iter<2; ++iter)
3069 {
3070 6630272 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3071
3072
2/2
✓ Branch 0 taken 3315136 times.
✓ Branch 1 taken 3315136 times.
6630272 if(iter==1) checkflag=scr->sflag[i]; //Placed
3073
3074
4/4
✓ Branch 0 taken 200805 times.
✓ Branch 1 taken 6429467 times.
✓ Branch 2 taken 133230 times.
✓ Branch 3 taken 67575 times.
6630272 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3075 {
3076 67575 rpos_handle_t rpos_handle;
3077
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3078 {
3079 57208 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3080 57208 screen_combo_modify_preroutine(rpos_handle);
3081 57208 }
3082
3083 67575 scr->data[i] = scr->secretcombo[checkflag-16+4];
3084 67575 scr->cset[i] = scr->secretcset[checkflag-16+4];
3085 67575 newflag = scr->secretflag[checkflag-16+4];
3086
3087
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3088 57208 screen_combo_modify_postroutine(rpos_handle);
3089 67575 }
3090 6630272 }
3091
3092
2/2
✓ Branch 0 taken 3247589 times.
✓ Branch 1 taken 67547 times.
3315136 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3093
3094
2/2
✓ Branch 0 taken 19890816 times.
✓ Branch 1 taken 3315136 times.
23205952 for(int32_t j=1; j<=6; j++) //Layers
3095 {
3096 19890816 mapscr* layer_scr = screen_handles[j].scr;
3097
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 13898720 times.
19890816 if (!layer_scr) continue;
3098
3099 5992096 int32_t newflag2 = -1;
3100
3101
2/2
✓ Branch 0 taken 11984192 times.
✓ Branch 1 taken 5992096 times.
17976288 for(int32_t iter=0; iter<2; ++iter)
3102 {
3103 11984192 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3104
3105
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 5992096 times.
11984192 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3106
3107
4/4
✓ Branch 0 taken 159433 times.
✓ Branch 1 taken 11824759 times.
✓ Branch 2 taken 136546 times.
✓ Branch 3 taken 22887 times.
11984192 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3108 {
3109 22887 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3110 22887 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3111 22887 newflag2 = layer_scr->secretflag[checkflag-16+4];
3112 22887 }
3113 11984192 }
3114
3115
2/2
✓ Branch 0 taken 5969209 times.
✓ Branch 1 taken 22887 times.
5992096 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3116 5992096 }
3117 3315136 }
3118 3380784 }
3119
3120
2/2
✓ Branch 0 taken 508074 times.
✓ Branch 1 taken 19209 times.
527283 for(word i=0; i<c; i++) // FFCs
3121 {
3122
6/6
✓ Branch 0 taken 468053 times.
✓ Branch 1 taken 40021 times.
✓ Branch 2 taken 15497 times.
✓ Branch 3 taken 492577 times.
✓ Branch 4 taken 3657 times.
✓ Branch 5 taken 11840 times.
508074 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3123 {
3124 496234 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3125
3126 //No placed flags yet
3127
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 496141 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 12 times.
496234 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3128 {
3129
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3130 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3131 else
3132 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3133 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3134 12 }
3135 496234 }
3136 527283 }
3137
3138 endhe:
3139
3140
1/2
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
19223 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3141 {
3142 if (from_active_screen)
3143 activated_timed_warp = true;
3144 scr->timedwarptics = 0;
3145 }
3146 19223 }
3147
3148 // x,y are world coordinates.
3149 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3150 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3151 13982906 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3152 {
3153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13982906 times.
13982906 if (!is_in_world_bounds(x, y)) return false;
3154
3155 13982906 bool found_cflag = false;
3156 13982906 bool found_nflag = false;
3157 13982906 bool single16 = false;
3158 13982906 rpos_t rpos = rpos_t::None;
3159
3160
2/2
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 97868060 times.
111848864 for (int32_t layer = -1; layer < 6; layer++)
3161 {
3162
2/2
✓ Branch 0 taken 97865958 times.
✓ Branch 1 taken 2102 times.
97868060 if (MAPFLAG2(layer, x, y) == flag)
3163 {
3164 2102 found_nflag = true;
3165 2102 break;
3166 }
3167 97865958 }
3168
3169
2/2
✓ Branch 0 taken 13982517 times.
✓ Branch 1 taken 97878647 times.
111861164 for (int32_t layer = -1; layer < 6; layer++)
3170 {
3171
2/2
✓ Branch 0 taken 97878258 times.
✓ Branch 1 taken 389 times.
97878647 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3172 {
3173 389 found_cflag = true;
3174 389 break;
3175 }
3176 97878258 }
3177
3178
2/2
✓ Branch 0 taken 97880342 times.
✓ Branch 1 taken 13982906 times.
111863248 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3179 {
3180
2/2
✓ Branch 0 taken 97865628 times.
✓ Branch 1 taken 14714 times.
97880342 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3181 {
3182
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14602 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14714 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3183 {
3184 112 rpos = COMBOPOS_REGION(x, y);
3185 112 }
3186
3/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14546 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
14602 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3187 {
3188 56 rpos = COMBOPOS_REGION(x, y);
3189 56 single16 = true;
3190 56 }
3191 14714 }
3192
3193
2/2
✓ Branch 0 taken 97877619 times.
✓ Branch 1 taken 2723 times.
97880342 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3194 {
3195
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2468 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2723 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3196 {
3197 255 rpos = COMBOPOS_REGION(x, y);
3198 255 }
3199
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
2468 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3200 {
3201 29 rpos = COMBOPOS_REGION(x, y);
3202 29 single16 = true;
3203 29 }
3204 2723 }
3205 97880342 }
3206
3207 13982906 out_rpos = rpos;
3208 13982906 out_single16 = single16;
3209
4/4
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 2102 times.
✓ Branch 2 taken 13980419 times.
✓ Branch 3 taken 385 times.
13982906 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3210 13982906 }
3211
3212 4604586 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3213 {
3214
8/8
✓ Branch 0 taken 4604346 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4602449 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4601929 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4600977 times.
4604586 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3215
3216 4600977 mapscr* scr = NULL;
3217 4600977 int32_t screen = -1;
3218 4600977 rpos_t trigger_rpos = rpos_t::None;
3219 4600977 bool single16 = false;
3220
3221 4600977 std::vector<std::pair<int, int>> coords;
3222
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y});
3223
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y});
3224
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y + 15});
3225
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y + 15});
3226 4600977 std::vector<rpos_t> rposes_seen;
3227
2/2
✓ Branch 0 taken 4598479 times.
✓ Branch 1 taken 18398387 times.
87336590 for (auto [x, y] : coords)
3228 {
3229
2/4
✓ Branch 0 taken 18398387 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18398387 times.
✗ Branch 3 not taken.
36796774 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3230
2/2
✓ Branch 0 taken 18184458 times.
✓ Branch 1 taken 213929 times.
18398387 if (rpos == rpos_t::None)
3231 213929 continue;
3232
3233
4/6
✓ Branch 0 taken 18184458 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18184458 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 18184447 times.
36368916 if (MAPFFCOMBOFLAG(x, y) == flag)
3234 {
3235
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3236 11 break;
3237 }
3238
3239 18184447 bool seen = false;
3240
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 22894140 times.
36877046 for (rpos_t r : rposes_seen)
3241 {
3242
2/2
✓ Branch 0 taken 18692599 times.
✓ Branch 1 taken 4201541 times.
22894140 if (r == rpos)
3243 {
3244 4201541 seen = true;
3245 4201541 break;
3246 }
3247 }
3248
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 4201541 times.
18184447 if (seen)
3249 4201541 continue;
3250
3251
1/2
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
13982906 rposes_seen.push_back(rpos);
3252
4/6
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13982906 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2487 times.
✓ Branch 5 taken 13980419 times.
27965812 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3253 {
3254
2/4
✓ Branch 0 taken 2487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2487 times.
✗ Branch 3 not taken.
4974 screen = get_screen_for_world_xy(x, y);
3255 2487 break;
3256 }
3257 }
3258
3259
3/4
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
✓ Branch 2 taken 2498 times.
✗ Branch 3 not taken.
4600977 if (screen != -1) scr = get_scr(screen);
3260
2/2
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
4600977 if (!scr) return false;
3261
3262
2/2
✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 452 times.
2498 if (trigger_rpos == rpos_t::None)
3263 {
3264 2046 checktrigger = true;
3265
1/2
✓ Branch 0 taken 2046 times.
✗ Branch 1 not taken.
2046 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3266 2046 }
3267 else
3268 {
3269 452 checktrigger = true;
3270
2/4
✓ Branch 0 taken 452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
452 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3271 }
3272
3273
1/2
✓ Branch 0 taken 2498 times.
✗ Branch 1 not taken.
2498 sfx(scr->secretsfx);
3274
3275
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2477 times.
2498 if(scr->flags6&fTRIGGERFPERM)
3276 {
3277
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 int32_t flags_remaining = findtrigger(screen); //Normal flags
3278
3279
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (flags_remaining)
3280 {
3281
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3282 12 setflag=false;
3283 12 }
3284
3285 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3286 // which case only the screen state for mSECRET may be set below.
3287
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
21 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3288 {
3289
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3290 6 }
3291 21 }
3292
3293
5/6
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 2384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1276 times.
2498 if (setflag && canPermSecret(cur_dmap, screen))
3294
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 463 times.
2089 if(!(scr->flags5&fTEMPSECRETS))
3295
1/2
✓ Branch 0 taken 813 times.
✗ Branch 1 not taken.
813 setmapflag(scr, mSECRET);
3296
3297 2498 return true;
3298 4604586 }
3299
3300 15390052 void update_slopes()
3301 {
3302
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 15390052 times.
15532408 for (auto& p : slopes)
3303 {
3304 142356 slope_object& s = p.second;
3305 142356 s.updateslope(); //sets old x/y poses
3306 }
3307 15390052 }
3308
3309 14930249 void update_freeform_combos()
3310 {
3311 14930249 ffscript_engine(false);
3312
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14906077 times.
14930249 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3313 {
3314 14906077 int wrap_right = world_w + 32;
3315 14906077 int wrap_bottom = world_h + 32;
3316
3317 488487769 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3318 473581692 mapscr* scr = ffc_handle.scr;
3319 473581692 ffcdata& thisffc = *ffc_handle.ffc;
3320
3321 // Combo 0?
3322
2/2
✓ Branch 0 taken 47283515 times.
✓ Branch 1 taken 426298177 times.
473581692 if(thisffc.data==0)
3323 426298177 return;
3324
3325 // Changer?
3326
2/2
✓ Branch 0 taken 562821 times.
✓ Branch 1 taken 46720694 times.
47283515 if(thisffc.flags&ffc_changer)
3327 562821 return;
3328
3329 // Stationary?
3330
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 46710850 times.
46720694 if(thisffc.flags&ffc_stationary)
3331 9844 return;
3332
3333 // Frozen because Hero's holding up an item?
3334
3/4
✓ Branch 0 taken 157429 times.
✓ Branch 1 taken 46553421 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 157429 times.
46710850 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3335 157429 return;
3336
3337 // Check for changers
3338
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 if (thisffc.link==0)
3339 {
3340 446641935 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3341
2/2
✓ Branch 0 taken 15506442 times.
✓ Branch 1 taken 415627414 times.
431133856 if (ffc_handle.id == other_ffc_handle.id)
3342 15506442 return true;
3343
3344 415627414 ffcdata& otherffc = *other_ffc_handle.ffc;
3345 // Combo 0?
3346
2/2
✓ Branch 0 taken 147056060 times.
✓ Branch 1 taken 268571354 times.
415627414 if(otherffc.data==0)
3347 268571354 return true;
3348
3349 // Not a changer?
3350
2/2
✓ Branch 0 taken 142874031 times.
✓ Branch 1 taken 4182029 times.
147056060 if(!(otherffc.flags&ffc_changer))
3351 142874031 return true;
3352
3353 // Ignore this changer?
3354
4/4
✓ Branch 0 taken 564215 times.
✓ Branch 1 taken 3617814 times.
✓ Branch 2 taken 308097 times.
✓ Branch 3 taken 3309717 times.
4182029 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3355 872312 return true;
3356
3357
3/4
✓ Branch 0 taken 2870799 times.
✓ Branch 1 taken 438918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3663 times.
3313380 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3358 ( // At exactly the same position,
3359
2/2
✓ Branch 0 taken 217547 times.
✓ Branch 1 taken 2653252 times.
2870799 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3360
2/2
✓ Branch 0 taken 2435705 times.
✓ Branch 1 taken 2653252 times.
217547 ||
3361 //or imprecision and close enough
3362
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5306504 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3363 )
3364 && //and...
3365
2/2
✓ Branch 0 taken 3663 times.
✓ Branch 1 taken 2870960 times.
2874623 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3366 {
3367 3663 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3368 3663 return false;
3369 }
3370
3371 2870960 return true;
3372 430082568 });
3373 15508079 }
3374
3375
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3376
4/4
✓ Branch 0 taken 15508079 times.
✓ Branch 1 taken 31045342 times.
✓ Branch 2 taken 15430786 times.
✓ Branch 3 taken 15614556 times.
46553421 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3377 {
3378
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 15431947 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
15614556 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3379 {
3380 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3381 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3382 97278 thisffc.x += linked_ffc->vx;
3383 97278 thisffc.y += linked_ffc->vy;
3384 97278 }
3385 else
3386 {
3387 15517278 thisffc.prev_changer_x = thisffc.x.getZLong();
3388 15517278 thisffc.prev_changer_y = thisffc.y.getZLong();
3389 15517278 thisffc.x += thisffc.vx;
3390 15517278 thisffc.y += thisffc.vy;
3391 15517278 thisffc.vx += thisffc.ax;
3392 15517278 thisffc.vy += thisffc.ay;
3393
3394
3395
2/2
✓ Branch 0 taken 1192093 times.
✓ Branch 1 taken 14325185 times.
15517278 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3396 {
3397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx>128) thisffc.vx=128;
3398
3399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx<-128) thisffc.vx=-128;
3400
3401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy>128) thisffc.vy=128;
3402
3403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy<-128) thisffc.vy=-128;
3404 14325185 }
3405 }
3406 15614556 }
3407 else
3408 {
3409
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
30938865 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3410 76132 thisffc.delay--;
3411 }
3412
3413 // Check if the FFC's off the side of the screen
3414
3415 // Left
3416
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 15681400 times.
15691849 if(thisffc.x<-32)
3417 {
3418
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3419 {
3420 253 thisffc.x = wrap_right+(thisffc.x+32);
3421 253 thisffc.solid_update(false);
3422 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3423 // Re-enable previous changer
3424 253 thisffc.changer_x = -1000;
3425 253 thisffc.changer_y = -1000;
3426 253 }
3427
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3428 {
3429 69 zc_ffc_set(thisffc, 0);
3430 69 thisffc.flags&=~ffc_carryover;
3431 69 }
3432 10449 }
3433 // Right
3434
2/2
✓ Branch 0 taken 15681219 times.
✓ Branch 1 taken 181 times.
15681400 else if(thisffc.x>=wrap_right)
3435 {
3436
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3437 {
3438 128 thisffc.x = thisffc.x-wrap_right-32;
3439 128 thisffc.solid_update(false);
3440 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3441 128 thisffc.changer_x = -1000;
3442 128 thisffc.changer_y = -1000;
3443 128 }
3444 else
3445 {
3446 53 zc_ffc_set(thisffc, 0);
3447 53 thisffc.flags&=~ffc_carryover;
3448 }
3449 181 }
3450
3451 // Top
3452
2/2
✓ Branch 0 taken 25806 times.
✓ Branch 1 taken 15666043 times.
15691849 if(thisffc.y<-32)
3453 {
3454
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25798 times.
25806 if(scr->flags6&fWRAPAROUNDFF)
3455 {
3456 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3457 8 thisffc.solid_update(false);
3458 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3459 8 thisffc.changer_x = -1000;
3460 8 thisffc.changer_y = -1000;
3461 8 }
3462
2/2
✓ Branch 0 taken 25481 times.
✓ Branch 1 taken 317 times.
25798 else if(thisffc.y<-64)
3463 {
3464 317 zc_ffc_set(thisffc, 0);
3465 317 thisffc.flags&=~ffc_carryover;
3466 317 }
3467 25806 }
3468 // Bottom
3469
2/2
✓ Branch 0 taken 15665175 times.
✓ Branch 1 taken 868 times.
15666043 else if(thisffc.y>=wrap_bottom)
3470 {
3471
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 115 times.
868 if(scr->flags6&fWRAPAROUNDFF)
3472 {
3473 753 thisffc.y = thisffc.y-wrap_bottom-32;
3474 753 thisffc.solid_update(false);
3475 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3476 753 thisffc.changer_x = -1000;
3477 753 thisffc.changer_y = -1000;
3478 753 }
3479 else
3480 {
3481 115 zc_ffc_set(thisffc, 0);
3482 115 thisffc.flags&=~ffc_carryover;
3483 }
3484 868 }
3485 15691849 thisffc.solid_update();
3486 442720120 });
3487 14906077 }
3488 14930249 }
3489
3490 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3491 {
3492 for(int q = 0; q < 7; ++q)
3493 {
3494 if(layers&(1<<q)) //if layer is to be checked
3495 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3496 return true;
3497 }
3498 return false;
3499 }
3500
3501 231 optional<int> nextscr(int screen, int dir)
3502 {
3503 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3505 462 return (m<<7) + s;
3506 231 }
3507
3508 1064 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3509 {
3510 1064 int32_t map = cur_map;
3511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1064 times.
1064 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3512 1064 return nextscr2(map, screen, dir);
3513 }
3514
3515 5582 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3516 {
3517 5582 screen = screen_index_direction(screen, (direction)dir);
3518
3519 // need to check for screens on other maps, 's' not valid, etc.
3520 5582 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3521
3522 // Fun fact: when a scrolling warp is triggered, this function
3523 // is never even called! - Saf
3524
2/2
✓ Branch 0 taken 3330 times.
✓ Branch 1 taken 2252 times.
6126 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3525 {
3526
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2252 switch(dir)
3527 {
3528 case up:
3529
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3530
3531 83 break;
3532
3533 case down:
3534
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 448 times.
527 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3535
3536 79 break;
3537
3538 case left:
3539
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3540
3541 209 break;
3542
3543 case right:
3544
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3545
3546 173 break;
3547 }
3548
3549 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3550 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3551 544 }
3552
3553 nowarp:
3554
4/4
✓ Branch 0 taken 5518 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5406 times.
5582 if(screen<0||screen>=128)
3555 176 return {-1, -1};
3556
3557 5406 return {map, screen};
3558 5582 }
3559
3560 403 optional<int> nextscr_mi(int mi, int dir)
3561 {
3562 403 int map = mi/MAPSCRSNORMAL;
3563 403 int screen = mi%MAPSCRSNORMAL;
3564 403 auto [m, s] = nextscr2(map, screen, dir);
3565
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3566 804 return (m<<7) + s;
3567 403 }
3568
3569 2297 void bombdoor(int32_t x,int32_t y)
3570 {
3571
2/2
✓ Branch 0 taken 2276 times.
✓ Branch 1 taken 21 times.
2297 if (!is_in_world_bounds(x, y))
3572 21 return;
3573
3574 2276 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3575 2276 mapscr* scr = rpos_handle.scr;
3576 2276 int screen = scr->screen;
3577 3084 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3578 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3579
3580
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2276 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3581 {
3582 69 scr->door[0]=dBOMBED;
3583 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3584 69 setmapflag(scr, mDOOR_UP);
3585 69 markBmap(-1, screen);
3586
3587
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3588 {
3589 69 setmapflag_mi(*v, mDOOR_DOWN);
3590 69 markBmap(-1,*v-(get_currdmap()<<7));
3591 69 }
3592 69 }
3593
3594
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2227 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2276 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3595 {
3596 39 scr->door[1]=dBOMBED;
3597 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3598 39 setmapflag(scr, mDOOR_DOWN);
3599 39 markBmap(-1, rpos_handle.screen);
3600
3601
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3602 {
3603 39 setmapflag_mi(*v, mDOOR_UP);
3604 39 markBmap(-1,*v-(get_currdmap()<<7));
3605 39 }
3606 39 }
3607
3608
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2209 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2276 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3609 {
3610 51 scr->door[2]=dBOMBED;
3611 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3612 51 setmapflag(scr, mDOOR_LEFT);
3613 51 markBmap(-1, rpos_handle.screen);
3614
3615
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3616 {
3617 51 setmapflag_mi(*v, mDOOR_RIGHT);
3618 51 markBmap(-1,*v-(get_currdmap()<<7));
3619 51 }
3620 51 }
3621
3622
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2190 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2276 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3623 {
3624 72 scr->door[3]=dBOMBED;
3625 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3626 72 setmapflag(scr, mDOOR_RIGHT);
3627 72 markBmap(-1, rpos_handle.screen);
3628
3629
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3630 {
3631 72 setmapflag_mi(*v, mDOOR_LEFT);
3632 72 markBmap(-1,*v-(get_currdmap()<<7));
3633 72 }
3634 72 }
3635 2297 }
3636
3637 7120005313 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3638 bool over, bool transp)
3639 {
3640 7120005313 auto& cmb = combobuf[cid];
3641
2/2
✓ Branch 0 taken 93673 times.
✓ Branch 1 taken 7119911640 times.
7120005313 if(cmb.animflags & AF_EDITOR_ONLY)
3642 93673 return;
3643
2/2
✓ Branch 0 taken 3924729734 times.
✓ Branch 1 taken 3195181906 times.
7119911640 if(over)
3644 {
3645
2/2
✓ Branch 0 taken 841117 times.
✓ Branch 1 taken 3923888617 times.
3924729734 if(cmb.animflags & AF_TRANSPARENT)
3646 841117 transp = !transp;
3647
2/2
✓ Branch 0 taken 328633561 times.
✓ Branch 1 taken 3596096173 times.
3924729734 if(transp)
3648 328633561 overcombotranslucent(dest, x, y, cid, cset, 128);
3649 3596096173 else overcombo(dest, x, y, cid, cset);
3650 3924729734 }
3651 3195181906 else putcombo(dest, x, y, cid, cset);
3652 7120005313 }
3653 7120013761 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3654 int32_t cset, byte layer, bool over, bool transp)
3655 {
3656
2/2
✓ Branch 0 taken 847534117 times.
✓ Branch 1 taken 6272479644 times.
7120013761 if (rpos != rpos_t::None)
3657 {
3658 6272479644 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3659
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 6271730120 times.
6272479644 if (plrpos != rpos_t::None)
3660 {
3661 6271730120 bool dosw = false;
3662
4/4
✓ Branch 0 taken 67998 times.
✓ Branch 1 taken 6271662122 times.
✓ Branch 2 taken 59550 times.
✓ Branch 3 taken 8448 times.
6271730120 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3663 {
3664
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3665 {
3666 draw_cmb(dest, x, y,
3667 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3668 }
3669 8448 dosw = true;
3670 8448 }
3671
4/4
✓ Branch 0 taken 35601615 times.
✓ Branch 1 taken 6236120057 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 35593167 times.
6271721672 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3672 {
3673 8448 dosw = true;
3674 8448 }
3675
2/2
✓ Branch 0 taken 6271713224 times.
✓ Branch 1 taken 16896 times.
6271730120 if (dosw)
3676 {
3677
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3678 {
3679 default: case swPOOF:
3680 break; //Nothing special here
3681 case swFLICKER:
3682 {
3683
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3684 8448 break; //Drawn this frame
3685 8448 return; //Not drawn this frame
3686 }
3687 case swRISE:
3688 {
3689 //Draw rising up
3690 y -= 8-(abs(Hero.switchhookclk-32)/4);
3691 break;
3692 }
3693 }
3694 8448 }
3695 6271721672 }
3696 6272471196 }
3697
3698 7120005313 draw_cmb(dest, x, y, cid, cset, over, transp);
3699 7120013761 }
3700
3701 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3702 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3703 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3704 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3705 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3706 //
3707 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3708 //
3709 // -16 < comboPositionX*16 + x < bitmapWidth
3710 // -16 < comboPositionY*16 + y < bitmapHeight
3711 //
3712 // The following start/end values are derived directly from the above.
3713 //
3714 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3715 44035950 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3716 {
3717 // if (bmp->clip)
3718 // {
3719 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3720 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3721 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3722 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3723 // return;
3724 // }
3725
3726
2/2
✓ Branch 0 taken 2404962 times.
✓ Branch 1 taken 41630988 times.
44035950 start_x = MAX(0, ceil((-15 - x) / 16.0));
3727
2/2
✓ Branch 0 taken 2412938 times.
✓ Branch 1 taken 41623012 times.
44035950 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3728
2/2
✓ Branch 0 taken 42497400 times.
✓ Branch 1 taken 1538550 times.
44035950 start_y = MAX(0, ceil((-15 - y) / 16.0));
3729
2/2
✓ Branch 0 taken 1874536 times.
✓ Branch 1 taken 42161414 times.
44035950 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3730 44035950 }
3731
3732 195720106 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3733 {
3734
1/2
✓ Branch 0 taken 195720106 times.
✗ Branch 1 not taken.
195720106 if(!show_ffcs) return;
3735 195720106 mapscr* scr = screen_handle.scr;
3736 195720106 mapscr* base_scr = screen_handle.base_scr;
3737
3738 195720106 y += playing_field_offset;
3739
3740 195720106 bool is_overhead = layer == -1000;
3741
2/2
✓ Branch 0 taken 53249630 times.
✓ Branch 1 taken 142470476 times.
195720106 bool is_bg_layer = layer < 0 && !is_overhead;
3742
2/2
✓ Branch 0 taken 35535090 times.
✓ Branch 1 taken 160185016 times.
195720106 int real_layer = is_bg_layer ? abs(layer) : layer;
3743
2/2
✓ Branch 0 taken 195720106 times.
✓ Branch 1 taken 5610067558 times.
5805787664 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3744 {
3745
2/2
✓ Branch 0 taken 217455144 times.
✓ Branch 1 taken 5392612414 times.
5610067558 if (base_scr->ffcs[i].data == 0)
3746 5392612414 continue;
3747
3/4
✓ Branch 0 taken 39536116 times.
✓ Branch 1 taken 177919028 times.
✓ Branch 2 taken 39536116 times.
✗ Branch 3 not taken.
217455144 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3748 ; // ffc is set negative, skip bg layer flag checks
3749 else
3750 {
3751
4/4
✓ Branch 0 taken 39536089 times.
✓ Branch 1 taken 177919055 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19768031 times.
217455144 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3752 19768031 continue;
3753
4/4
✓ Branch 0 taken 39535883 times.
✓ Branch 1 taken 158151230 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19767825 times.
197687113 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3754 19767825 continue;
3755
4/4
✓ Branch 0 taken 158156192 times.
✓ Branch 1 taken 19763096 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 138388134 times.
177919288 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3756 138388134 continue;
3757 }
3758
3759
6/6
✓ Branch 0 taken 3311080 times.
✓ Branch 1 taken 36220074 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3305970 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
39531154 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3760 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3761
3762 39528670 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3763 39528670 }
3764 195720106 }
3765 177528574 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3766 {
3767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177528574 times.
177528574 if(!show_ffcs) return;
3768 359982090 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3769 182453516 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3770 182453516 do_ffc_layer(bmp, layer, handle, 0, 0);
3771 182453516 });
3772 177528574 }
3773 110564490 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3774 {
3775 110564490 mapscr* scr = screen_handle.scr;
3776 110564490 mapscr* base_scr = screen_handle.base_scr;
3777
3778
4/4
✓ Branch 0 taken 69334564 times.
✓ Branch 1 taken 41229926 times.
✓ Branch 2 taken 41229926 times.
✓ Branch 3 taken 110564490 times.
110564490 if (type == -3 || type == -4)
3779 {
3780 82459852 y += playing_field_offset;
3781
3782
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
82459852 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3783 {
3784 if (base_scr->ffcs[i].data == 0)
3785 continue;
3786
3787 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3788 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3789
3790 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3791 }
3792 return;
3793 }
3794
3795 110564490 x -= viewport.x;
3796 110564490 y -= viewport.y - playing_field_offset;
3797
3798 110564490 bool over = true, transp = false;
3799 110564490 int layer = screen_handle.layer;
3800
3801
7/8
✓ Branch 0 taken 86296232 times.
✓ Branch 1 taken 24268258 times.
✓ Branch 2 taken 15026723 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62975483 times.
✓ Branch 5 taken 23320749 times.
✓ Branch 6 taken 3907648 times.
✓ Branch 7 taken 5333887 times.
110564490 switch(type ? type : layer)
3802 {
3803 case -2: //push blocks
3804
2/2
✓ Branch 0 taken 21745557 times.
✓ Branch 1 taken 41229926 times.
62975483 if (scr)
3805 {
3806
2/2
✓ Branch 0 taken 3827218032 times.
✓ Branch 1 taken 62318575 times.
3863254799 for(int32_t i=0; i<176; i++)
3807 {
3808 3827218032 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3809
3810
10/10
✓ Branch 0 taken 3827047688 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3825570483 times.
✓ Branch 3 taken 1477205 times.
✓ Branch 4 taken 3824937244 times.
✓ Branch 5 taken 633239 times.
✓ Branch 6 taken 53394531 times.
✓ Branch 7 taken 3771542713 times.
✓ Branch 8 taken 100280201 times.
✓ Branch 9 taken 57139160 times.
3870809545 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3811
6/8
✓ Branch 0 taken 3822054595 times.
✓ Branch 1 taken 50511882 times.
✓ Branch 2 taken 3822054595 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3822054595 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43591513 times.
✓ Branch 7 taken 3778463082 times.
3824937244 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3812 {
3813
4/4
✓ Branch 0 taken 5124570 times.
✓ Branch 1 taken 782430 times.
✓ Branch 2 taken 3849 times.
✓ Branch 3 taken 5120721 times.
206467402 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3814 5907000 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3815 5907000 }
3816 3841509242 }
3817 62318575 }
3818 103548501 return;
3819
3820 case -1: //over combo
3821
1/2
✓ Branch 0 taken 23320749 times.
✗ Branch 1 not taken.
23320749 if (scr)
3822 {
3823
2/2
✓ Branch 0 taken 4104451824 times.
✓ Branch 1 taken 23320749 times.
4127772573 for(int32_t i=0; i<176; i++)
3824 {
3825
2/2
✓ Branch 0 taken 4085121904 times.
✓ Branch 1 taken 19329920 times.
4104451824 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3826 {
3827
4/4
✓ Branch 0 taken 15574819 times.
✓ Branch 1 taken 3755101 times.
✓ Branch 2 taken 22336 times.
✓ Branch 3 taken 15552483 times.
19329920 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3828 19329920 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3829 19329920 }
3830 4104451824 }
3831 23320749 }
3832 23320749 return;
3833
3834 case 1:
3835 case 4:
3836 case 5:
3837 case 6:
3838
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15026723 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15026723 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3839 {
3840
1/2
✓ Branch 0 taken 15026723 times.
✗ Branch 1 not taken.
15026723 if (scr)
3841 {
3842
2/2
✓ Branch 0 taken 13331916 times.
✓ Branch 1 taken 1694807 times.
15026723 if(base_scr->layeropacity[layer-1]!=255)
3843 1694807 transp = true;
3844 15026723 break;
3845 }
3846 }
3847 return;
3848
3849 case 2:
3850
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3907648 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3907648 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3851 {
3852
1/2
✓ Branch 0 taken 3907648 times.
✗ Branch 1 not taken.
3907648 if (scr)
3853 {
3854
2/2
✓ Branch 0 taken 3671362 times.
✓ Branch 1 taken 236286 times.
3907648 if(base_scr->layeropacity[layer-1]!=255)
3855 236286 transp = true;
3856
3857
2/2
✓ Branch 0 taken 3760193 times.
✓ Branch 1 taken 147455 times.
3907648 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3858 147455 over = false;
3859
3860 3907648 break;
3861 }
3862 }
3863 return;
3864
3865 case 3:
3866
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5333887 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5333887 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3867 {
3868
1/2
✓ Branch 0 taken 5333887 times.
✗ Branch 1 not taken.
5333887 if (scr)
3869 {
3870
2/2
✓ Branch 0 taken 5258611 times.
✓ Branch 1 taken 75276 times.
5333887 if(base_scr->layeropacity[layer-1]!=255)
3871 75276 transp = true;
3872
3873
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 237618 times.
5333887 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3874
2/2
✓ Branch 0 taken 274272 times.
✓ Branch 1 taken 5059615 times.
5333887 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3875 237618 over = false;
3876
3877 5333887 break;
3878 }
3879 }
3880 return;
3881 }
3882
3883 int start_x, end_x, start_y, end_y;
3884 24268258 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3885
2/2
✓ Branch 0 taken 24268258 times.
✓ Branch 1 taken 257485684 times.
281753942 for (int cy = start_y; cy < end_y; cy++)
3886 {
3887
2/2
✓ Branch 0 taken 3898086039 times.
✓ Branch 1 taken 257485684 times.
4155571723 for (int cx = start_x; cx < end_x; cx++)
3888 {
3889 3898086039 int i = cx + cy*16;
3890
4/4
✓ Branch 0 taken 3441235004 times.
✓ Branch 1 taken 456851035 times.
✓ Branch 2 taken 11831072 times.
✓ Branch 3 taken 3429403932 times.
3898086039 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3891 3898086039 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3892 3898086039 }
3893 257485684 }
3894 69334564 }
3895
3896 279535975 bool lenscheck(mapscr* scr, int layer)
3897 {
3898
4/4
✓ Branch 0 taken 279359403 times.
✓ Branch 1 taken 176572 times.
✓ Branch 2 taken 176572 times.
✓ Branch 3 taken 279535975 times.
279535975 if(layer < 0 || layer > 6) return true;
3899
2/2
✓ Branch 0 taken 259692525 times.
✓ Branch 1 taken 19843450 times.
279535975 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3900 {
3901
2/2
✓ Branch 0 taken 209793109 times.
✓ Branch 1 taken 49899416 times.
259692525 if(!layer) return true;
3902
8/8
✓ Branch 0 taken 34936541 times.
✓ Branch 1 taken 174856568 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34677571 times.
✓ Branch 4 taken 146134 times.
✓ Branch 5 taken 259680 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34497169 times.
209793109 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3903 586216 return false;
3904 209353737 }
3905 else
3906 {
3907
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19843450 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19843450 times.
19843450 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3908 return false;
3909 }
3910 229197187 return true;
3911 279359403 }
3912
3913 165168059 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3914 {
3915 165168059 bool showlayer = true;
3916 165168059 mapscr* base_scr = screen_handle.base_scr;
3917 165168059 int layer = screen_handle.layer;
3918
2/2
✓ Branch 0 taken 46586195 times.
✓ Branch 1 taken 118581864 times.
165168059 int target = type ? type : layer;
3919
3/4
✓ Branch 0 taken 118581864 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22483787 times.
✓ Branch 3 taken 24102408 times.
165168059 switch(target)
3920 {
3921 case -2:
3922
1/2
✓ Branch 0 taken 22483787 times.
✗ Branch 1 not taken.
22483787 if(!show_layer_push)
3923 showlayer = false;
3924 22483787 break;
3925
3926 case -1:
3927
1/2
✓ Branch 0 taken 24102408 times.
✗ Branch 1 not taken.
24102408 if(!show_layer_over)
3928 showlayer = false;
3929 24102408 break;
3930
3931 case 1: case 2: case 3:
3932 case 4: case 5: case 6:
3933 118581864 showlayer = show_layers[target];
3934 118581864 break;
3935 }
3936
3937
2/2
✓ Branch 0 taken 46586195 times.
✓ Branch 1 taken 118581864 times.
165168059 if(!type)
3938 {
3939
2/2
✓ Branch 0 taken 118445666 times.
✓ Branch 1 taken 136198 times.
118581864 if(!lenscheck(base_scr,layer))
3940 136198 showlayer = false;
3941 118581864 }
3942
3943
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 165031861 times.
165168059 if(showlayer)
3944 {
3945
6/6
✓ Branch 0 taken 69426512 times.
✓ Branch 1 taken 95605349 times.
✓ Branch 2 taken 24360206 times.
✓ Branch 3 taken 45066306 times.
✓ Branch 4 taken 91948 times.
✓ Branch 5 taken 24268258 times.
165031861 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3946 {
3947 69334564 do_scrolling_layer(bmp, type, screen_handle, x, y);
3948
4/4
✓ Branch 0 taken 24268258 times.
✓ Branch 1 taken 45066306 times.
✓ Branch 2 taken 22269756 times.
✓ Branch 3 taken 1998502 times.
69334564 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3949
2/2
✓ Branch 0 taken 1997926 times.
✓ Branch 1 taken 576 times.
1999078 if(mblock2.draw(bmp,layer))
3950 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3951 69334564 }
3952 165031861 }
3953 165168059 }
3954
3955 107036242 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3956 {
3957 107036242 bool showlayer = true;
3958
3959
2/4
✓ Branch 0 taken 107036242 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 107036242 times.
107036242 if(layer >= 0 && layer <= 6)
3960 {
3961 107036242 showlayer = show_layers[layer];
3962
3963
2/2
✓ Branch 0 taken 106909640 times.
✓ Branch 1 taken 126602 times.
107036242 if(!lenscheck(origin_scr,layer))
3964 126602 showlayer = false;
3965 107036242 }
3966
3967
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 106909640 times.
107036242 if (showlayer)
3968 106909640 do_primitives(bmp, layer);
3969 107036242 }
3970
3971 // Called by do_walkflags
3972 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3973 {
3974 newcombo const &c = combobuf[cmbdat];
3975
3976 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3977
3978 int32_t xx = x-xofs;
3979 int32_t yy = y+playing_field_offset-yofs;
3980
3981 int32_t bridgedetected = 0;
3982
3983 for(int32_t i=0; i<4; i++)
3984 {
3985 int32_t tx=((i&2)<<2)+xx - viewport.x;
3986 int32_t ty=((i&1)<<3)+yy - viewport.y;
3987 int32_t tx2=((i&2)<<2)+x - viewport.x;
3988 int32_t ty2=((i&1)<<3)+y - viewport.y;
3989 for (int32_t j = lyr-1; j <= 1; j++)
3990 {
3991 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3992 {
3993 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3994 {
3995 bridgedetected |= (1<<i);
3996 }
3997 }
3998 else
3999 {
4000 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4001 {
4002 bridgedetected |= (1<<i);
4003 }
4004 }
4005 }
4006 if ((bridgedetected & (1<<i)))
4007 {
4008 if (i >= 3) break;
4009 else continue;
4010 }
4011 bool doladdercheck = true;
4012
4013 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4014 {
4015 for(int32_t k=0; k<8; k+=2)
4016 for(int32_t j=0; j<8; j+=2)
4017 if(((k+j)/2)%2)
4018 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4019 }
4020 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4021 {
4022 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4023 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4024 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4025 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4026 }
4027
4028 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4029 {
4030 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4031 {
4032 for(int32_t k=0; k<8; k+=2)
4033 for(int32_t j=0; j<8; j+=2)
4034 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4035 }
4036 else
4037 {
4038 int32_t color = makecol(178,36,36);
4039
4040 if(isstepable(cmbdat)&& (!doladdercheck))
4041 color=makecol(165,105,8);
4042 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4043 color=makecol(170,170,170);
4044
4045 rectfill(dest,tx,ty,tx+7,ty+7,color);
4046 }
4047 }
4048 }
4049
4050 // Draw damage combos
4051 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4052 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4053 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4054
4055 if(dmg)
4056 {
4057 int32_t color = makecol(255,255,0);
4058 if (bridgedetected <= 0)
4059 {
4060 for(int32_t k=0; k<16; k+=2)
4061 for(int32_t j=0; j<16; j+=2)
4062 if(((k+j)/2)%2)
4063 {
4064 int32_t x0 = x - viewport.x;
4065 int32_t y0 = y - viewport.y;
4066 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4067 }
4068 }
4069 else
4070 {
4071 for(int32_t i=0; i<4; i++)
4072 {
4073 if (!(bridgedetected & (1<<i)))
4074 {
4075 int32_t tx=((i&2)<<2)+x - viewport.x;
4076 int32_t ty=((i&1)<<3)+y - viewport.y;
4077 for(int32_t k=0; k<8; k+=2)
4078 for(int32_t j=0; j<8; j+=2)
4079 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4080 }
4081 }
4082 }
4083 }
4084 }
4085 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4086 {
4087 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4088 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4089 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4090 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4091 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4092 newcombo const &c = combobuf[cmbdat];
4093
4094 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4095
4096 int32_t xx = x-viewport.x;
4097 int32_t yy = y+playing_field_offset-viewport.y;
4098
4099 int32_t bridgedetected = 0;
4100
4101 // Draw damage combos
4102 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4103
4104 for(int32_t i=0; i<4; i++)
4105 {
4106 int32_t tx=((i&2)<<2)+xx;
4107 int32_t ty=((i&1)<<3)+yy;
4108 int32_t tx2=((i&2)<<2)+x;
4109 int32_t ty2=((i&1)<<3)+y;
4110 for (int32_t m = lyr-1; m <= 1; m++)
4111 {
4112 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4113 {
4114 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4115 {
4116 bridgedetected |= (1<<i);
4117 }
4118 }
4119 else
4120 {
4121 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4122 {
4123 bridgedetected |= (1<<i);
4124 }
4125 }
4126 }
4127 if ((bridgedetected & (1<<i)))
4128 continue;
4129 bool doladdercheck = true;
4130
4131 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4132 {
4133 for(int32_t k=0; k<8; k+=2)
4134 for(int32_t j=0; j<8; j+=2)
4135 if(((k+j)/2)%2)
4136 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4137 }
4138 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4139 {
4140 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4141 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4142 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4143 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4144 }
4145
4146 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4147 {
4148 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4149 {
4150 for(int32_t k=0; k<8; k+=2)
4151 for(int32_t j=0; j<8; j+=2)
4152 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4153 }
4154 else
4155 {
4156 ALLEGRO_COLOR* color = &col_solid;
4157
4158 if(isstepable(cmbdat)&& (!doladdercheck))
4159 color=&col_stepable;
4160 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4161 color=&col_lhook;
4162
4163 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4164 }
4165 }
4166
4167 if(dmg)
4168 {
4169 for(int32_t k=0; k<8; k+=2)
4170 for(int32_t j=0; j<8; j+=2)
4171 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4172 }
4173 }
4174 }
4175
4176 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4177 {
4178 newcombo const &c = combobuf[cmbdat];
4179
4180 int32_t xx = x-xofs-viewport.x;
4181 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4182
4183 for(int32_t i=0; i<4; i++)
4184 {
4185 int32_t tx=((i&2)<<2)+xx;
4186 int32_t ty=((i&1)<<3)+yy;
4187
4188 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4189 {
4190 int32_t color = vc(10);
4191
4192 rectfill(dest,tx,ty,tx+7,ty+7,color);
4193 }
4194 }
4195 }
4196 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4197 {
4198 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4199 newcombo const &c = combobuf[cmbdat];
4200
4201 int32_t xx = x-viewport.x;
4202 int32_t yy = y+playing_field_offset-viewport.y;
4203
4204 for(int32_t i=0; i<4; i++)
4205 {
4206 int32_t tx=((i&2)<<2)+xx;
4207 int32_t ty=((i&1)<<3)+yy;
4208
4209 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4210 {
4211 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4212 }
4213 }
4214 }
4215
4216 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4217 {
4218 for(auto cx = 0; cx < 256; cx += 16)
4219 {
4220 for(auto cy = 0; cy < 176; cy += 16)
4221 {
4222 if(isSVLadder(cx,cy))
4223 {
4224 auto nx = cx+x, ny = cy+y;
4225 if(cy && !isSVLadder(cx,cy-16))
4226 line(dest,nx,ny,nx+15,ny,c);
4227 rectfill(dest,nx,ny,nx+3,ny+15,c);
4228 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4229 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4230 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4231 }
4232 else if(isSVPlatform(cx,cy))
4233 {
4234 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4235 }
4236 }
4237 }
4238 }
4239 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4240 {
4241 for(auto cx = 0; cx < 256; cx += 16)
4242 {
4243 for(auto cy = 0; cy < 176; cy += 16)
4244 {
4245 if(isSVLadder(cx,cy))
4246 {
4247 auto nx = cx+x, ny = cy+y;
4248 if(cy && !isSVLadder(cx,cy-16))
4249 al_draw_line(nx,ny,nx+15,ny,c,1);
4250 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4251 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4252 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4253 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4254 }
4255 else if(isSVPlatform(cx,cy))
4256 {
4257 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4258 }
4259 }
4260 }
4261 }
4262
4263 // Walkflags L4 cheat
4264 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4265 {
4266 if (!show_walkflags)
4267 return;
4268
4269 start_info_bmp();
4270
4271 mapscr* scr = screen_handles[0].scr;
4272 for(int32_t i=0; i<176; i++)
4273 {
4274 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4275 }
4276
4277 for(int32_t k=0; k<2; k++)
4278 {
4279 scr = screen_handles[k + 1].scr;
4280
4281 if (scr)
4282 {
4283 for(int32_t i=0; i<176; i++)
4284 {
4285 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4286 }
4287 }
4288 }
4289
4290 end_info_bmp();
4291 }
4292
4293 void do_walkflags(int32_t x, int32_t y)
4294 {
4295 if (!show_walkflags)
4296 return;
4297
4298 x += -viewport.x;
4299 y += playing_field_offset - viewport.y;
4300
4301 start_info_bmp();
4302
4303 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4304 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4305 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4306
4307 end_info_bmp();
4308 }
4309
4310 // Effectflags L4 cheat
4311 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4312 {
4313 if(show_effectflags)
4314 {
4315 start_info_bmp();
4316
4317 for(int32_t i=0; i<176; i++)
4318 {
4319 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4320 }
4321
4322 end_info_bmp();
4323 }
4324 }
4325
4326 400489 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4327 {
4328 400489 int map = scr->map;
4329 400489 int screen = scr->screen;
4330
4331
2/2
✓ Branch 0 taken 2803423 times.
✓ Branch 1 taken 400489 times.
3203912 for(int32_t lyr = 0; lyr < 7; ++lyr)
4332 {
4333 2803423 mapscr* scr = get_scr_layer(map, screen, lyr);
4334
2/2
✓ Branch 0 taken 1829718 times.
✓ Branch 1 taken 973705 times.
2803423 if (!scr->is_valid()) continue;
4335
4336
2/2
✓ Branch 0 taken 322030368 times.
✓ Branch 1 taken 1829718 times.
323860086 for(int32_t q = 0; q < 176; ++q)
4337 {
4338 322030368 newcombo const& cmb = combobuf[scr->data[q]];
4339
2/2
✓ Branch 0 taken 320498295 times.
✓ Branch 1 taken 1532073 times.
322030368 if(cmb.type == cTORCH)
4340 {
4341 1532073 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4342 1532073 }
4343 322030368 }
4344 1829718 }
4345 400489 }
4346
4347 400489 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4348 {
4349 400489 word c = scr->numFFC();
4350
2/2
✓ Branch 0 taken 704965 times.
✓ Branch 1 taken 400489 times.
1105454 for(int q = 0; q < c; ++q)
4351 {
4352 704965 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4353
2/2
✓ Branch 0 taken 690157 times.
✓ Branch 1 taken 14808 times.
704965 if(cmb.type == cTORCH)
4354 {
4355 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4356 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4357 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4358 14808 }
4359 704965 }
4360 400489 }
4361
4362 struct nearby_screen_t
4363 {
4364 int screen;
4365 int offx;
4366 int offy;
4367 screen_handles_t screen_handles;
4368 };
4369 typedef std::vector<nearby_screen_t> nearby_screens_t;
4370
4371 16081834 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4372 {
4373 16081834 nearby_screens_t nearby_screens;
4374
4375 16081834 mapscr* base_scr = origin_scr;
4376
1/2
✓ Branch 0 taken 16081834 times.
✗ Branch 1 not taken.
16081834 auto& nearby_screen = nearby_screens.emplace_back();
4377 16081834 nearby_screen.screen = cur_screen;
4378
1/2
✓ Branch 0 taken 16081834 times.
✗ Branch 1 not taken.
16081834 nearby_screen.screen_handles = create_screen_handles(base_scr);
4379
4380 16081834 return nearby_screens;
4381
1/2
✓ Branch 0 taken 16081834 times.
✗ Branch 1 not taken.
16081834 }
4382
4383 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4384 {
4385 48296 nearby_screens_t nearby_screens;
4386
4387
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4388
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4389
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4390
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4391
4392
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4393
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4394
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4395
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4396
4397
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4398 {
4399
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4400 {
4401 169672 int screen = cur_screen + x + y*16;
4402
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4403
4404
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4405
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4406
4407
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4408
4409
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4410 169672 nearby_screen.screen = screen;
4411 169672 nearby_screen.offx = offx;
4412 169672 nearby_screen.offy = offy;
4413
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4414 169672 }
4415 79928 }
4416
4417 48296 return nearby_screens;
4418
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4419
4420 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4421 {
4422 3658 nearby_screens_t nearby_screens;
4423
4424
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4425
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4426
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4427
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4428
4429
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4430
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4431
4432
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4433 {
4434
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4435 {
4436 18600 int screen = -1;
4437 mapscr* base_scr;
4438 int offx, offy;
4439
4440 18600 mapscr* maze_scr = maze_state.scr;
4441 18600 int maze_screen = maze_scr->screen;
4442
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4443
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4444 18600 int maze_screen_dx = x - maze_screen_x;
4445 18600 int maze_screen_dy = y - maze_screen_y;
4446 18600 int exitdir = maze_scr->exitdir;
4447
4448 bool should_draw_maze_screen;
4449
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4450 {
4451 9548 should_draw_maze_screen = true;
4452 9548 }
4453 else
4454 {
4455 9052 should_draw_maze_screen = true;
4456
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4457
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4458
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4459 }
4460
4461
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4462 {
4463 16048 screen = maze_state.scr->screen;
4464 16048 base_scr = maze_state.scr;
4465
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4466 16048 }
4467
4468
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4469 {
4470 2552 screen = cur_screen + x + y*16;
4471
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4472
4473
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4474
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4475
4476
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4477 2552 }
4478
4479
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4480 18600 nearby_screen.screen = screen;
4481 18600 nearby_screen.offx = offx;
4482 18600 nearby_screen.offy = offy;
4483
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4484 18600 }
4485 7308 }
4486
4487 3658 return nearby_screens;
4488
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4489
4490 16133788 static nearby_screens_t get_nearby_screens()
4491 {
4492
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 16124574 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
16133788 if (maze_state.active && maze_state.loopy)
4493 3658 return get_nearby_screens_smooth_maze();
4494
4495
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 16081834 times.
16130130 if (is_in_scrolling_region())
4496 48296 return get_nearby_screens_scrolling_region();
4497
4498 16081834 return get_nearby_screens_non_scrolling_region();
4499 16133788 }
4500
4501 209966575 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4502 {
4503
2/2
✓ Branch 0 taken 211751177 times.
✓ Branch 1 taken 209966575 times.
421717752 for (auto& nearby_screen : nearby_screens)
4504 211751177 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4505 209966575 }
4506
4507 145288604 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4508 {
4509
2/2
✓ Branch 0 taken 32309070 times.
✓ Branch 1 taken 112979534 times.
145288604 if(layer != msgstr_layer) return;
4510
2/2
✓ Branch 0 taken 16133026 times.
✓ Branch 1 taken 16176044 times.
32309070 if(!dest) dest = framebuf;
4511
4512
2/2
✓ Branch 0 taken 1461257 times.
✓ Branch 1 taken 30847813 times.
32309070 if(!(msg_bg_display_buf->clip))
4513 {
4514 1461257 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4515 1461257 }
4516
4517
2/2
✓ Branch 0 taken 1461257 times.
✓ Branch 1 taken 30847813 times.
32309070 if(!(msg_portrait_display_buf->clip))
4518 {
4519 1461257 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4520 1461257 }
4521
4522
2/2
✓ Branch 0 taken 1488071 times.
✓ Branch 1 taken 30820999 times.
32309070 if(!(msg_txt_display_buf->clip))
4523 {
4524 1488071 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4525 1488071 }
4526 145288604 }
4527
4528 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4529
4530 64535152 static void set_draw_screen_clip(BITMAP* bmp)
4531 {
4532 64535152 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4533 64535152 }
4534
4535 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4536 {
4537 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4538
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4539 12905 return; // no sprites to draw remaining
4540 // Just clips sprites if in a repeating, smooth maze.
4541
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4542
4543
4544
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4545 {
4546 int maze_screen = maze_state.scr->screen;
4547 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4548 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4549 }
4550
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4551 {
4552 30698 sprite* spr = *it;
4553
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4554 {
4555 2930 decorations.draw2(dest,true);
4556 2930 Hero.draw(dest);
4557 2930 decorations.draw(dest,true);
4558
4559 // Draw enemies holding the Hero directly above the Hero
4560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4561 {
4562 if(((enemy*)guys.spr(i))->type == eeWALK)
4563 if(((eStalfos*)guys.spr(i))->hashero)
4564 guys.spr(i)->draw(dest);
4565 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4566 if(((eWallM*)guys.spr(i))->hashero)
4567 guys.spr(i)->draw(dest);
4568 }
4569 2930 }
4570
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4571 {
4572 2930 mblock2.draw(dest, -1);
4573 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4574 2930 }
4575
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4576 {
4577 e->draw(dest);
4578 e->draw2(dest); // used specifically for eGleeok/esGleeok
4579 }
4580 24838 else spr->draw(dest);
4581 30698 ++it;
4582 }
4583
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4584 clear_clip_rect(dest);
4585 17580 }
4586
4587 11991 static void draw_high_darkness(BITMAP* dest)
4588 {
4589 11991 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
4590 11991 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4591
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4592 {
4593 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4594 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4595 }
4596
4597 11991 color_map = trans_table2;
4598
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4599 {
4600 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
4601 if(get_qr(qr_NEWDARK_TRANS_STACKING))
4602 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4603 }
4604 else
4605 {
4606 11991 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
4607 11991 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4608 }
4609 11991 color_map = trans_table;
4610
4611 11991 set_clip_rect(dest, 0, 0, dest->w, dest->h);
4612 11991 do_primitives(dest, SPLAYER_DARKROOM_OVER);
4613 11991 }
4614
4615 16176044 static void draw_screen_post_passive_subscreen(BITMAP* dest, bool any_dark)
4616 {
4617 16176044 draw_msgstr(6, dest);
4618
4619
1/2
✓ Branch 0 taken 16176044 times.
✗ Branch 1 not taken.
16176044 if (get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
4620 draw_msgstr(6, dest);
4621
4622
6/6
✓ Branch 0 taken 1905831 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 453730 times.
✓ Branch 3 taken 1452101 times.
✓ Branch 4 taken 441739 times.
✓ Branch 5 taken 11991 times.
16176044 if (get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
4623 11991 draw_high_darkness(dest);
4624
4625 16176044 _do_current_ffc_layer(dest, 7);
4626 16176044 draw_msgstr(7, dest);
4627 16176044 }
4628
4629 // Draws to framebuf.
4630 //
4631 // But if drawPassiveSubscreenSeparate is true: framebuf_no_passive_subscreen will also contain all
4632 // draws excluding the passive subscreen.
4633 16133788 void draw_screen(bool showhero, bool runGeneric, bool drawPassiveSubscreenSeparate)
4634 {
4635 16133788 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4636 16133788 clear_info_bmp();
4637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
16133788 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4638 {
4639 FFCore.doScriptMenuDraws();
4640 return;
4641 }
4642
4643
2/2
✓ Branch 0 taken 613639 times.
✓ Branch 1 taken 15520149 times.
16133788 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4644
4645 16133788 BITMAP* dest = framebuf;
4646 16133788 clear_bitmap(dest);
4647 16133788 clear_clip_rect(dest);
4648
4649 16133788 int32_t cmby2=0;
4650
4651 // Draw some background layers
4652 16133788 clear_bitmap(scrollbuf);
4653
4654 16133788 auto nearby_screens = get_nearby_screens();
4655
4656
2/2
✓ Branch 0 taken 16130858 times.
✓ Branch 1 taken 2930 times.
16133788 if (!classic_draw)
4657 {
4658
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4659 {
4660
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(scrollbuf, layer);
4661
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4662 do_primitives(scrollbuf, layer);
4663 11720 }
4664 2930 }
4665
4666 // Handle layer 2/3 possibly being background layers.
4667
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (classic_draw) // weird ordering (-3 > -2)
4668 {
4669
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
32398034 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4670 16267176 mapscr* base_scr = screen_handles[0].base_scr;
4671
2/2
✓ Branch 0 taken 16125055 times.
✓ Branch 1 taken 142121 times.
16267176 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4672 142121 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4673 16267176 });
4674
4675 16130858 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4676
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15988737 times.
16130858 if (l2bg)
4677 {
4678
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 do_layer_primitives(scrollbuf, 2);
4679
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 particles.draw(scrollbuf, true, 2);
4680 142121 }
4681
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
16130858 _do_current_ffc_layer(scrollbuf, -2);
4682
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15988737 times.
16130858 if (l2bg)
4683
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 draw_msgstr(2, scrollbuf);
4684 16130858 }
4685
4686
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4687 16270106 mapscr* base_scr = screen_handles[0].base_scr;
4688
2/2
✓ Branch 0 taken 16035542 times.
✓ Branch 1 taken 234564 times.
16270106 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4689 234564 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4690 16270106 });
4691
4692
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15899224 times.
16133788 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4693 {
4694
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 do_layer_primitives(scrollbuf, 3);
4695
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 particles.draw(scrollbuf, true, 3);
4696 234564 }
4697
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, -3);
4698
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15899224 times.
16133788 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4699
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 draw_msgstr(3, scrollbuf);
4700
4701
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
4702 {
4703
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4704 // Actually use proper ordering (-3 < -2)
4705
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4706 2930 mapscr* base_scr = screen_handles[0].base_scr;
4707
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4708 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4709 2930 });
4710
4711 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4713 {
4714 do_layer_primitives(scrollbuf, 2);
4715 particles.draw(scrollbuf, true, 2);
4716 }
4717
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4719 draw_msgstr(2, scrollbuf);
4720
4721
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4722
4723
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -1);
4724
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4725 2930 }
4726
4727 // Draw the main combo screens ("layer 0").
4728
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4729 16270106 mapscr* base_scr = screen_handles[0].base_scr;
4730
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16270106 times.
16270106 if (lenscheck(base_scr, 0))
4731 {
4732 16270106 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4733 16270106 }
4734 16270106 });
4735
4736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
16133788 if (lenscheck(hero_scr, 0))
4737 {
4738
2/2
✓ Branch 0 taken 466467 times.
✓ Branch 1 taken 15667321 times.
16133788 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4739
3/4
✓ Branch 0 taken 466467 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 462331 times.
470603 if(mblock2.draw(scrollbuf,0))
4740
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4741 16133788 }
4742
4743 // Lens hints, then primitives, then particles.
4744
6/10
✓ Branch 0 taken 16123759 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16123759 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16123759 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
16133788 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4745 {
4746
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4747
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4748 5876 }
4749
4750
2/4
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16133788 times.
✗ Branch 3 not taken.
16133788 if(show_layers[0] && lenscheck(hero_scr,0))
4751
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(scrollbuf, 0);
4752
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(scrollbuf, true, 0);
4753
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, 0);
4754
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(0, scrollbuf);
4755
4756
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(scrollbuf);
4757
4758 16133788 bool hero_draw_done = false;
4759
4/6
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16099036 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 16099036 times.
✗ Branch 5 not taken.
16133788 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4760
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15790529 times.
16133788 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4761 {
4762
4/4
✓ Branch 0 taken 15788650 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15700266 times.
15790529 if(showhero && is_cave_walking)
4763 {
4764 88384 hero_draw_done = true;
4765
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4766 {
4767 34752 cmby2=16;
4768 34752 }
4769
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4770 {
4771 53632 cmby2=-16;
4772 53632 }
4773
4774
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4775
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4776
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4777
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4778
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4779
4780
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4781
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4782
4783
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4784 {
4785
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4786
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4787 15232 }
4788 88384 }
4789 15790529 }
4790
4791
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16133788 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4792 {
4793 Hero.draw_under(scrollbuf);
4794 decorations.draw2(scrollbuf,true);
4795 Hero.draw(scrollbuf);
4796 decorations.draw(scrollbuf,true);
4797 hero_draw_done = true;
4798 }
4799
4800
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4801 16270106 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4802 16270106 });
4803
4804
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(scrollbuf, 1);
4805
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(scrollbuf, true, 1);
4806
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, 1);
4807
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(1, scrollbuf);
4808
4809 // Handle layer 2 NOT being used as background layers.
4810
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4811 16270106 mapscr* base_scr = screen_handles[0].base_scr;
4812
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 16127985 times.
16270106 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4813 16127985 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4814 16270106 });
4815
4816
2/2
✓ Branch 0 taken 15991667 times.
✓ Branch 1 taken 142121 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4817 {
4818
1/2
✓ Branch 0 taken 15991667 times.
✗ Branch 1 not taken.
15991667 do_layer_primitives(scrollbuf, 2);
4819
1/2
✓ Branch 0 taken 15991667 times.
✗ Branch 1 not taken.
15991667 particles.draw(scrollbuf, true, 2);
4820 15991667 }
4821
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, 2);
4822
2/2
✓ Branch 0 taken 15991667 times.
✓ Branch 1 taken 142121 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4823
1/2
✓ Branch 0 taken 15991667 times.
✗ Branch 1 not taken.
15991667 draw_msgstr(2, scrollbuf);
4824
4825
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4826
4827
2/2
✓ Branch 0 taken 15790529 times.
✓ Branch 1 taken 343259 times.
16133788 if(get_qr(qr_LAYER12UNDERCAVE))
4828 {
4829
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4830 {
4831 hero_draw_done = true;
4832 if(Hero.getAction()==climbcovertop)
4833 {
4834 cmby2=16;
4835 }
4836 else if(Hero.getAction()==climbcoverbottom)
4837 {
4838 cmby2=-16;
4839 }
4840
4841 decorations.draw2(scrollbuf,true);
4842 Hero.draw(scrollbuf);
4843 decorations.draw(scrollbuf,true);
4844 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4845 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4846
4847 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4848 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4849
4850 if(int32_t(Hero.getX())&15)
4851 {
4852 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4853 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4854 }
4855 }
4856 343259 }
4857
4858
2/2
✓ Branch 0 taken 466467 times.
✓ Branch 1 taken 15667321 times.
16133788 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4859 {
4860
1/2
✓ Branch 0 taken 15667321 times.
✗ Branch 1 not taken.
31470960 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4861 15803639 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4862
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 1324724 times.
15803639 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4863 {
4864 1324724 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4865 1324724 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4866 1324724 }
4867 15803639 });
4868
4869
1/2
✓ Branch 0 taken 15667321 times.
✗ Branch 1 not taken.
15667321 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4870 15667321 }
4871
4872 // Show walkflags cheat
4873
2/4
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16133788 times.
16133788 if (show_walkflags || show_effectflags)
4874 {
4875 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4876 do_walkflags(screen_handles, offx, offy);
4877 do_effectflags(screen_handles[0].base_scr, offx, offy);
4878 });
4879
4880 do_walkflags(0, 0);
4881 }
4882
4883
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4884
4885 // Lens hints, doors etc.
4886
4/8
✓ Branch 0 taken 16123759 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16123759 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16123759 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16133788 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4887 {
4888
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4889 {
4890
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4891
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4892 4153 }
4893
4894
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4895
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4896 10029 }
4897
4898 // Blit those layers onto dest (framebuf)
4899
4900
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(dest);
4901
4902
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 blit(scrollbuf, dest, 0, 0, 0, 0, 256, 232);
4903
4904 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4905 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4906
4907 // Draw the subscreen, without clipping
4908
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6882404 times.
16133788 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4909 {
4910 9251384 bool dotime = false;
4911
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4912
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(dest, 0, 0, dotime, sspUP);
4913 9251384 }
4914
4915 // Draw some sprites onto dest
4916
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_clip_rect(dest,0,0,256,232);
4917
4918
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 16034292 times.
16133788 if(!(pricesdisplaybuf->clip))
4919 {
4920
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,dest,0,0,0,playing_field_offset,256,176);
4921 99496 }
4922
4923
5/6
✓ Branch 0 taken 16088162 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081834 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133788 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4924 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4925
4926
4/4
✓ Branch 0 taken 16131909 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 16043525 times.
✓ Branch 3 taken 88384 times.
16133788 if(showhero && !hero_draw_done)
4927 {
4928
1/2
✓ Branch 0 taken 16043525 times.
✗ Branch 1 not taken.
16043525 Hero.draw_under(dest);
4929
4930
3/4
✓ Branch 0 taken 16043525 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15902140 times.
16043525 if(Hero.isSwimming())
4931 {
4932
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(dest,true);
4933
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(dest);
4934
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(dest,true);
4935 141385 hero_draw_done = true;
4936 141385 }
4937 16043525 }
4938
4939 16133788 set<sprite*, SpriteSorter> sorted_sprites;
4940 16133788 vector<sprite*> temp_sprites;
4941 16133788 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4942 {
4943 sorted_sprites.insert(&spr);
4944 return false;
4945 };
4946
4947
2/2
✓ Branch 0 taken 16130858 times.
✓ Branch 1 taken 2930 times.
16133788 if (classic_draw)
4948 {
4949
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 16104763 times.
16130858 if(drawguys)
4950 {
4951
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 14122089 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
16104763 if(get_qr(qr_NOFLICKER) || (frame&1))
4952 {
4953 // Just clips sprites if in a repeating, smooth maze.
4954
2/2
✓ Branch 0 taken 15103964 times.
✓ Branch 1 taken 9214 times.
15113178 bool do_clip = maze_state.active && maze_state.loopy;
4955
4956
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4957 {
4958 if (do_clip)
4959 {
4960 Ewpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4961 Lwpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4962 }
4963 else
4964 {
4965 Ewpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4966 Lwpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4967 }
4968 }
4969
3/4
✓ Branch 0 taken 24918252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15113178 times.
24918252 for(int32_t i=0; i<Ewpns.Count(); i++)
4970 {
4971
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✓ Branch 3 taken 9554132 times.
9805074 if(((weapon *)Ewpns.spr(i))->behind)
4972
2/4
✓ Branch 0 taken 250942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✗ Branch 3 not taken.
250942 Ewpns.spr(i)->draw(dest);
4973 9805074 }
4974
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
4975
4976
3/4
✓ Branch 0 taken 21297169 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15113178 times.
21297169 for(int32_t i=0; i<Lwpns.Count(); i++)
4977 {
4978
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✓ Branch 3 taken 4976995 times.
6183991 if(((weapon *)Lwpns.spr(i))->behind)
4979
2/4
✓ Branch 0 taken 1206996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✗ Branch 3 not taken.
1206996 Lwpns.spr(i)->draw(dest);
4980 6183991 }
4981
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
4982
4983
6/6
✓ Branch 0 taken 10376314 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 9028014 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
15113178 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4984 {
4985
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9698367 times.
9702025 if (do_clip)
4986
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS)!=0);
4987 else
4988
1/2
✓ Branch 0 taken 9698367 times.
✗ Branch 1 not taken.
9698367 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
4989 9702025 }
4990
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
4991
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(dest);
4992 else
4993
1/2
✓ Branch 0 taken 15109520 times.
✗ Branch 1 not taken.
15109520 guys.draw(dest,true);
4994
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
4995 {
4996 3658 int maze_screen = maze_state.scr->screen;
4997
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4998
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4999 3658 }
5000
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_NPC_DRAW);
5001
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5002
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5003
5004
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 chainlinks.draw(dest,true);
5005
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5006 //Lwpns.draw(dest,true);
5007
5008
3/4
✓ Branch 0 taken 24918252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15113178 times.
24918252 for(int32_t i=0; i<Ewpns.Count(); i++)
5009 {
5010
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✓ Branch 3 taken 250942 times.
9805074 if(!((weapon *)Ewpns.spr(i))->behind)
5011
2/4
✓ Branch 0 taken 9554132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✗ Branch 3 not taken.
9554132 Ewpns.spr(i)->draw(dest);
5012 9805074 }
5013
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5014
5015
3/4
✓ Branch 0 taken 21297169 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15113178 times.
21297169 for(int32_t i=0; i<Lwpns.Count(); i++)
5016 {
5017
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✓ Branch 3 taken 1206996 times.
6183991 if(!((weapon *)Lwpns.spr(i))->behind)
5018
2/4
✓ Branch 0 taken 4976995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✗ Branch 3 not taken.
4976995 Lwpns.spr(i)->draw(dest);
5019 6183991 }
5020
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5021
5022
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5023
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(dest);
5024 else
5025
1/2
✓ Branch 0 taken 15109520 times.
✗ Branch 1 not taken.
15109520 items.draw(dest,true);
5026
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5027 {
5028 3658 int maze_screen = maze_state.scr->screen;
5029
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5030
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5031 3658 }
5032
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5033
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5034
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5035 15113178 }
5036 else
5037 {
5038
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5039 {
5040
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
5041
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(dest);
5042 505372 }
5043
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
5044
5045
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5046 {
5047
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
5048 Lwpns.spr(i)->draw(dest);
5049 231146 }
5050
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
5051
5052
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5053 {
5054
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5055 228620 }
5056
5057
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(dest,false);
5058
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5059
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(dest,false);
5060
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5061 //Lwpns.draw(dest,false);
5062
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(dest,false);
5063
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_NPC_DRAW);
5064
5065
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5066 {
5067
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
5068 {
5069
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(dest);
5070 496727 }
5071 505372 }
5072
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5073
5074
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5075 {
5076
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
5077 {
5078
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(dest);
5079 231146 }
5080 231146 }
5081
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5082 }
5083
5084
1/2
✓ Branch 0 taken 16104763 times.
✗ Branch 1 not taken.
16104763 guys.draw2(dest,true);
5085 16104763 }
5086
5087
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16130858 times.
16130858 if(mirror_portal.destdmap > -1)
5088 mirror_portal.draw(dest);
5089
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
16130858 portals.draw(dest,true);
5090
5091
4/4
✓ Branch 0 taken 16128979 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 16040595 times.
16130858 if(showhero && !is_cave_walking)
5092 {
5093
2/2
✓ Branch 0 taken 15580545 times.
✓ Branch 1 taken 460050 times.
16040595 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5094 {
5095
1/2
✓ Branch 0 taken 15580545 times.
✗ Branch 1 not taken.
15580545 mblock2.draw(dest,-1);
5096
1/2
✓ Branch 0 taken 15580545 times.
✗ Branch 1 not taken.
15580545 do_primitives(dest, SPLAYER_MOVINGBLOCK);
5097 15580545 }
5098
2/2
✓ Branch 0 taken 15899210 times.
✓ Branch 1 taken 141385 times.
16040595 if(!hero_draw_done)
5099 {
5100
8/12
✓ Branch 0 taken 15899210 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15899210 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15880040 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15880040 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15880040 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15897840 times.
15899210 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5101 {
5102
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15880725 times.
15899210 Hero.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0);
5103 18485 }
5104
5105
6/8
✓ Branch 0 taken 15899210 times.
✓ Branch 1 taken 15880725 times.
✓ Branch 2 taken 15899210 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15899210 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15885146 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5106 {
5107
1/2
✓ Branch 0 taken 15885146 times.
✗ Branch 1 not taken.
15885146 decorations.draw2(dest,true);
5108
1/2
✓ Branch 0 taken 15885146 times.
✗ Branch 1 not taken.
15885146 Hero.draw(dest);
5109
1/2
✓ Branch 0 taken 15885146 times.
✗ Branch 1 not taken.
15885146 decorations.draw(dest,true);
5110 15885146 hero_draw_done = true;
5111 15885146 }
5112 15899210 }
5113 16040595 }
5114
5115
3/4
✓ Branch 0 taken 56548426 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✓ Branch 3 taken 16130858 times.
56548426 for(int32_t i=0; i<guys.Count(); i++)
5116 {
5117
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16520322 times.
✓ Branch 3 taken 23897246 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALK)
5118 {
5119
3/4
✓ Branch 0 taken 16520322 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✓ Branch 3 taken 16512357 times.
16520322 if(((eStalfos*)guys.spr(i))->hashero)
5120 {
5121
2/4
✓ Branch 0 taken 7965 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✗ Branch 3 not taken.
7965 guys.spr(i)->draw(dest);
5122 7965 }
5123 16520322 }
5124
5125
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 39910406 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALLM)
5126 {
5127
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
5128 {
5129
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(dest);
5130 1329 }
5131 507162 }
5132
5133
11/20
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40417568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40417568 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40417568 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40417568 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 40417568 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40417568 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40417568 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1523506 times.
✓ Branch 19 taken 38894062 times.
40417568 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5134 {
5135 //Jumping enemies in front of Hero.
5136
2/4
✓ Branch 0 taken 1523506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1523506 times.
✗ Branch 3 not taken.
1523506 guys.spr(i)->draw(dest);
5137 1523506 }
5138
1/2
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
40417568 do_primitives(dest, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5139 40417568 }
5140 16130858 }
5141 else
5142 {
5143
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5144 {
5145
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5146
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5147 25837 auto add_spr_shadow = [&](sprite& spr)
5148 {
5149 22907 sorted_sprites.insert(&spr);
5150
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5151 {
5152
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5153 1291 sorted_sprites.insert(shadow);
5154 1291 temp_sprites.push_back(shadow);
5155 1291 }
5156 22907 return false;
5157 };
5158
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5159
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5160
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5161
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5162 2930 }
5163
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5164 {
5165
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5166
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5167 {
5168
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5169
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5170
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5171 640 }
5172 2930 }
5173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5174 sorted_sprites.insert(&mirror_portal);
5175
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5176
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5177
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5178 }
5179 16133788 auto sprite_it = sorted_sprites.begin();
5180
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5181
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5182
5183 // Draw some layers onto dest
5184
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(dest);
5185
5/6
✓ Branch 0 taken 16088162 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081834 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133788 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5186 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5187
5188 // Handle layer 3 NOT being used as background layers.
5189
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5190 16270106 mapscr* base_scr = screen_handles[0].base_scr;
5191
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 16035542 times.
16270106 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5192 16035542 do_layer(dest, 0, screen_handles[3], offx, offy);
5193 16270106 });
5194
5195
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5196
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5197
5198
2/2
✓ Branch 0 taken 15899224 times.
✓ Branch 1 taken 234564 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5199 {
5200
1/2
✓ Branch 0 taken 15899224 times.
✗ Branch 1 not taken.
15899224 do_layer_primitives(dest, 3);
5201
1/2
✓ Branch 0 taken 15899224 times.
✗ Branch 1 not taken.
15899224 particles.draw(dest, true, 3);
5202 15899224 }
5203
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 3);
5204
2/2
✓ Branch 0 taken 15899224 times.
✓ Branch 1 taken 234564 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5205
1/2
✓ Branch 0 taken 15899224 times.
✗ Branch 1 not taken.
15899224 draw_msgstr(3);
5206
5207
5208
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5209 16270106 do_layer(dest, 0, screen_handles[4], offx, offy);
5210 16270106 });
5211
5212
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5213
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5214
5215
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(dest, 4);
5216
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(dest, true, 4);
5217
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 4);
5218
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(4);
5219
5220
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5221 16270106 do_layer(dest, -1, screen_handles[0], offx, offy);
5222
2/2
✓ Branch 0 taken 14402748 times.
✓ Branch 1 taken 1867358 times.
16270106 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5223 {
5224 1867358 do_layer(dest, -1, screen_handles[1], offx, offy);
5225 1867358 do_layer(dest, -1, screen_handles[2], offx, offy);
5226 1867358 }
5227 16270106 });
5228
5229
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(dest, SPLAYER_OVERHEAD_CMB);
5230
5231 // Draw some flying sprites onto dest
5232
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 clear_clip_rect(dest);
5233
5/6
✓ Branch 0 taken 16088162 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081834 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133788 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5234 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5235
5236
2/2
✓ Branch 0 taken 16130858 times.
✓ Branch 1 taken 2930 times.
16133788 if (classic_draw)
5237 {
5238 //Jumping Hero and jumping enemies are drawn on this layer.
5239
5/8
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16130858 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16130858 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 16116794 times.
16130858 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5240 {
5241
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(dest,false);
5242
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(dest);
5243
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(dest,true);
5244
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5245
5246
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5247 {
5248
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5249 {
5250
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(dest);
5251 239 }
5252 2742 }
5253
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_LWEAP_ABOVE_DRAW);
5254
5255
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(dest,false);
5256 14064 }
5257
5258
5/6
✓ Branch 0 taken 3872989 times.
✓ Branch 1 taken 12257869 times.
✓ Branch 2 taken 44341460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12257869 times.
48214449 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5259 {
5260
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5261 {
5262
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(dest);
5263 4912666 }
5264 44341460 }
5265 else
5266 {
5267
3/4
✓ Branch 0 taken 12206966 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✓ Branch 3 taken 3872989 times.
12206966 for(int32_t i=0; i<guys.Count(); i++)
5268 {
5269
13/22
✓ Branch 0 taken 8333977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997572 times.
✓ Branch 5 taken 1336405 times.
✓ Branch 6 taken 6997572 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6997572 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6997572 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6478745 times.
✓ Branch 13 taken 518827 times.
✓ Branch 14 taken 6478745 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6478745 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6478745 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 6478745 times.
8333977 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5270 {
5271
2/4
✓ Branch 0 taken 1855232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1855232 times.
✗ Branch 3 not taken.
1855232 guys.spr(i)->draw(dest);
5272 1855232 }
5273 8333977 }
5274 }
5275
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
16130858 do_primitives(dest, SPLAYER_NPC_AIRBORNE_DRAW);
5276 16130858 }
5277
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5278
5279 // Draw the Moving Fairy above layer 3
5280
3/4
✓ Branch 0 taken 19457924 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3324136 times.
✓ Branch 3 taken 16133788 times.
19457924 for(int32_t i=0; i<items.Count(); i++)
5281
6/8
✓ Branch 0 taken 3324136 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70250 times.
✓ Branch 3 taken 3253886 times.
✓ Branch 4 taken 70250 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60536 times.
✓ Branch 7 taken 9714 times.
3384672 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5282
2/4
✓ Branch 0 taken 60536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60536 times.
✗ Branch 3 not taken.
60536 items.spr(i)->draw(dest);
5283
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(dest, SPLAYER_FAIRYITEM_DRAW);
5284
5285 // Draw some layers onto dest
5286
5287
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(dest);
5288
5289
2/2
✓ Branch 0 taken 16119436 times.
✓ Branch 1 taken 14352 times.
16133788 if (lightbeam_present)
5290 {
5291 14352 color_map = trans_table2;
5292
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5293
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(dest, lightbeam_bmp, 0, playing_field_offset);
5294 else
5295
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, dest, 0, 0, 0, playing_field_offset, 256, 176);
5296 14352 color_map = trans_table;
5297 14352 }
5298
5299
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5300 16270106 do_layer(dest, 0, screen_handles[5], offx, offy);
5301 16270106 });
5302
5303
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5304
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5305
5306
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(dest, 5);
5307
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(dest, true, 5);
5308
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 5);
5309
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(5);
5310
5311
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, -1000); // 'overhead' freeform combos
5312
5313
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(dest, SPLAYER_OVERHEAD_FFC);
5314
5315
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5316 16270106 do_layer(dest, 0, screen_handles[6], offx, offy);
5317 16270106 });
5318
5319
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5320
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, word(-1));
5321
5322
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(dest, 6);
5323
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(dest, true, 6);
5324
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 6);
5325
5326 16133788 bool any_dark = false;
5327
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5328 16270106 mapscr* base_scr = screen_handles[0].scr;
5329 16270106 any_dark |= is_dark(base_scr);
5330 16270106 });
5331
5332 // Handle low drawn darkness
5333
4/4
✓ Branch 0 taken 1863575 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1516676 times.
✓ Branch 3 taken 346899 times.
16133788 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5334 {
5335
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5336 353133 mapscr* base_scr = screen_handles[0].scr;
5337 353133 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5338 353133 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5339 353133 });
5340
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 if(showhero)
5341
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 Hero.calc_darkroom_hero(0, -playing_field_offset);
5342
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5343 353133 mapscr* base_scr = screen_handles[0].scr;
5344
2/2
✓ Branch 0 taken 348403 times.
✓ Branch 1 taken 4730 times.
353133 if (!is_dark(base_scr))
5345 {
5346 4730 offy += playing_field_offset;
5347 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5348 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5349 4730 }
5350 353133 });
5351 346899 }
5352
5353 //Darkroom if under the subscreen
5354
6/6
✓ Branch 0 taken 1863575 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1409845 times.
✓ Branch 3 taken 453730 times.
✓ Branch 4 taken 334908 times.
✓ Branch 5 taken 1074937 times.
16133788 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5355 {
5356
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
5357
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334908 times.
334908 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5359 {
5360 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5361 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5362 }
5363
5364 334908 color_map = trans_table2;
5365
2/2
✓ Branch 0 taken 15523 times.
✓ Branch 1 taken 319385 times.
334908 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5366 {
5367
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
5368
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5369
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5370 15523 }
5371 else
5372 {
5373
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
5374
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5375 }
5376 334908 color_map = trans_table;
5377
5378
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, 0, dest->w, dest->h);
5379
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_OVER);
5380 334908 }
5381
5382
3/6
✓ Branch 0 taken 51954 times.
✓ Branch 1 taken 16081834 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51954 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16133788 if (is_in_scrolling_region() && lensclk && !FFCore.system_suspend[susptLENS])
5383 {
5384 draw_lens_over(dest);
5385 --lensclk;
5386 }
5387
5388 // Draw some text on dest
5389
5390
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_clip_rect(dest,0,0,256,232);
5391
5392
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5393
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(6);
5394
5395 // Draw the subscreen, without clipping
5396
2/2
✓ Branch 0 taken 6882404 times.
✓ Branch 1 taken 9251384 times.
16133788 if(get_qr(qr_SUBSCREENOVERSPRITES))
5397 {
5398
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6840148 times.
6882404 if (drawPassiveSubscreenSeparate)
5399
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 blit(dest, framebuf_no_passive_subscreen, 0, 0, 0, 0, dest->w, dest->h);
5400
5401
2/4
✓ Branch 0 taken 6882404 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6882404 times.
✗ Branch 3 not taken.
6882404 put_passive_subscr(dest, 0, 0, game->should_show_time(), sspUP);
5402
5403
1/2
✓ Branch 0 taken 6882404 times.
✗ Branch 1 not taken.
6882404 do_primitives(dest, 7);
5404
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6840148 times.
6882404 if (drawPassiveSubscreenSeparate)
5405
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 do_primitives(framebuf_no_passive_subscreen, 7);
5406 6882404 }
5407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251384 times.
9251384 else if (!classic_draw)
5408 do_primitives(dest, 7);
5409
5410
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_screen_post_passive_subscreen(dest, any_dark);
5411
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 16091532 times.
16133788 if (drawPassiveSubscreenSeparate)
5412
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 draw_screen_post_passive_subscreen(framebuf_no_passive_subscreen, any_dark);
5413
5414
2/2
✓ Branch 0 taken 15632242 times.
✓ Branch 1 taken 31766030 times.
16133788 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5415
3/4
✓ Branch 0 taken 15520149 times.
✓ Branch 1 taken 168133 times.
✓ Branch 2 taken 15520149 times.
✗ Branch 3 not taken.
15632242 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5416
5417
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15688282 times.
15690213 for(sprite* spr : temp_sprites)
5418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5419 79220342 }
5420
5421 // TODO: separate setting door data and drawing door
5422 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5423 {
5424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5425
5426 28153 int32_t d=scr->door_combo_set;
5427
5428
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5429 {
5430 case dt_wall:
5431 case dt_walk:
5432 if(!even_walls)
5433 break;
5434 [[fallthrough]];
5435 case dt_pass:
5436
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5437 1036 break;
5438 [[fallthrough]];
5439 case dt_lock:
5440 case dt_shut:
5441 case dt_boss:
5442 case dt_olck:
5443 case dt_osht:
5444 case dt_obos:
5445 case dt_bomb:
5446
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5447 {
5448 case up:
5449 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5450 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5451 7259 scr->sflag[pos] = 0;
5452 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5453 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5454 7259 scr->sflag[pos+1] = 0;
5455 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5456 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5457 7259 scr->sflag[pos+16] = 0;
5458 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5459 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5460 7259 scr->sflag[pos+16+1] = 0;
5461
5462
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5463 {
5464 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5465 1824 DoorComboSets[d].doorcombo_u[type][0],
5466 1824 DoorComboSets[d].doorcset_u[type][0]);
5467 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5468 1824 DoorComboSets[d].doorcombo_u[type][1],
5469 1824 DoorComboSets[d].doorcset_u[type][1]);
5470 1824 }
5471
5472 7259 break;
5473
5474 case down:
5475 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5476 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5477 6784 scr->sflag[pos] = 0;
5478 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5479 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5480 6784 scr->sflag[pos+1] = 0;
5481 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5482 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5483 6784 scr->sflag[pos+16] = 0;
5484 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5485 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5486 6784 scr->sflag[pos+16+1] = 0;
5487
5488
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5489 {
5490 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5491 1321 DoorComboSets[d].doorcombo_d[type][2],
5492 1321 DoorComboSets[d].doorcset_d[type][2]);
5493 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5494 1321 DoorComboSets[d].doorcombo_d[type][3],
5495 1321 DoorComboSets[d].doorcset_d[type][3]);
5496 1321 }
5497
5498 6784 break;
5499
5500 case left:
5501 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5502 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5503 6362 scr->sflag[pos] = 0;
5504 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5505 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5506 6362 scr->sflag[pos+1] = 0;
5507 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5508 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5509 6362 scr->sflag[pos+16] = 0;
5510 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5511 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5512 6362 scr->sflag[pos+16+1] = 0;
5513 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5514 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5515 6362 scr->sflag[pos+32] = 0;
5516 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5517 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5518 6362 scr->sflag[pos+32+1] = 0;
5519
5520
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5521 {
5522 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5523 1489 DoorComboSets[d].doorcombo_l[type][0],
5524 1489 DoorComboSets[d].doorcset_l[type][0]);
5525 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5526 1489 DoorComboSets[d].doorcombo_l[type][2],
5527 1489 DoorComboSets[d].doorcset_l[type][2]);
5528 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5529 1489 DoorComboSets[d].doorcombo_l[type][4],
5530 1489 DoorComboSets[d].doorcset_l[type][4]);
5531 1489 }
5532
5533 6362 break;
5534
5535 case right:
5536 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5537 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5538 6712 scr->sflag[pos] = 0;
5539 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5540 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5541 6712 scr->sflag[pos+1] = 0;
5542 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5543 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5544 6712 scr->sflag[pos+16] = 0;
5545 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5546 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5547 6712 scr->sflag[pos+16+1] = 0;
5548 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5549 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5550 6712 scr->sflag[pos+32] = 0;
5551 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5552 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5553 6712 scr->sflag[pos+32+1] = 0;
5554
5555
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5556 {
5557 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5558 1654 DoorComboSets[d].doorcombo_r[type][0],
5559 1654 DoorComboSets[d].doorcset_r[type][0]);
5560 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5561 1654 DoorComboSets[d].doorcombo_r[type][2],
5562 1654 DoorComboSets[d].doorcset_r[type][2]);
5563 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5564 1654 DoorComboSets[d].doorcombo_r[type][4],
5565 1654 DoorComboSets[d].doorcset_r[type][4]);
5566 1654 }
5567
5568 6712 break;
5569 }
5570
5571 27117 break;
5572
5573 default:
5574 break;
5575 }
5576 28153 }
5577
5578 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5579 {
5580 706556 int32_t door_combo_set = scr->door_combo_set;
5581 706556 int32_t x = (pos&15)<<4;
5582 706556 int32_t y = (pos&0xF0);
5583 706556 int32_t d = door_combo_set;
5584 706556 x += offx;
5585 706556 y += offy;
5586
5587
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5588 {
5589 case up:
5590 322272 overcombo2(dest,x,y,
5591 161136 DoorComboSets[d].bombdoorcombo_u[0],
5592 161136 DoorComboSets[d].bombdoorcset_u[0]);
5593 322272 overcombo2(dest,x+16,y,
5594 161136 DoorComboSets[d].bombdoorcombo_u[1],
5595 161136 DoorComboSets[d].bombdoorcset_u[1]);
5596 161136 break;
5597
5598 case down:
5599 359286 overcombo2(dest,x,y,
5600 179643 DoorComboSets[d].bombdoorcombo_d[0],
5601 179643 DoorComboSets[d].bombdoorcset_d[0]);
5602 359286 overcombo2(dest,x+16,y,
5603 179643 DoorComboSets[d].bombdoorcombo_d[1],
5604 179643 DoorComboSets[d].bombdoorcset_d[1]);
5605 179643 break;
5606
5607 case left:
5608 392706 overcombo2(dest,x,y,
5609 196353 DoorComboSets[d].bombdoorcombo_l[0],
5610 196353 DoorComboSets[d].bombdoorcset_l[0]);
5611 392706 overcombo2(dest,x,y+16,
5612 196353 DoorComboSets[d].bombdoorcombo_l[1],
5613 196353 DoorComboSets[d].bombdoorcset_l[1]);
5614 392706 overcombo2(dest,x,y+16,
5615 196353 DoorComboSets[d].bombdoorcombo_l[2],
5616 196353 DoorComboSets[d].bombdoorcset_l[2]);
5617 196353 break;
5618
5619 case right:
5620 338848 overcombo2(dest,x,y,
5621 169424 DoorComboSets[d].bombdoorcombo_r[0],
5622 169424 DoorComboSets[d].bombdoorcset_r[0]);
5623 338848 overcombo2(dest,x,y+16,
5624 169424 DoorComboSets[d].bombdoorcombo_r[1],
5625 169424 DoorComboSets[d].bombdoorcset_r[1]);
5626 338848 overcombo2(dest,x,y+16,
5627 169424 DoorComboSets[d].bombdoorcombo_r[2],
5628 169424 DoorComboSets[d].bombdoorcset_r[2]);
5629 169424 break;
5630 }
5631 706556 }
5632
5633 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5634 {
5635
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5636 25173 return;
5637
5638 int32_t doortype;
5639
5640
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5641 {
5642 case dWALL:
5643 doortype=dt_wall;
5644 break;
5645
5646 case dWALK:
5647 doortype=dt_walk;
5648 break;
5649
5650 case dOPEN:
5651 12492 doortype=dt_pass;
5652 12492 break;
5653
5654 case dLOCKED:
5655 910 doortype=dt_lock;
5656 910 break;
5657
5658 case dUNLOCKED:
5659 1553 doortype=dt_olck;
5660 1553 break;
5661
5662 case dSHUTTER:
5663
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5664 {
5665 doortype=dt_osht;
5666 get_screen_state(scr->screen).open_doors = -4;
5667 break;
5668 }
5669
5670 [[fallthrough]];
5671 case d1WAYSHUTTER:
5672 3714 doortype=dt_shut;
5673 3714 break;
5674
5675 case dOPENSHUTTER:
5676 1694 doortype=dt_osht;
5677 1694 break;
5678
5679 case dBOSS:
5680 172 doortype=dt_boss;
5681 172 break;
5682
5683 case dOPENBOSS:
5684 67 doortype=dt_obos;
5685 67 break;
5686
5687 case dBOMBED:
5688 1138 doortype=dt_bomb;
5689 1138 break;
5690
5691 default:
5692 655 return;
5693 }
5694
5695
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5696 {
5697 case up:
5698 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5699 5629 break;
5700
5701 case down:
5702 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5703 5770 break;
5704
5705 case left:
5706 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5707 5111 break;
5708
5709 case right:
5710 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5711 5230 break;
5712 }
5713 47568 }
5714
5715 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5716 {
5717 /*
5718 #define dWALL 0 // 000 0
5719 #define dBOMB 6 // 011 0
5720 #define 8 // 100 0
5721 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5722 */
5723
5724
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5725 91 return;
5726
5727 int32_t doortype;
5728
5729
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5730 {
5731 case dWALL:
5732 doortype=dt_wall;
5733 break;
5734
5735 case dWALK:
5736 doortype=dt_walk;
5737 break;
5738
5739 case dOPEN:
5740 50 doortype=dt_pass;
5741 50 break;
5742
5743 case dLOCKED:
5744 doortype=dt_lock;
5745 break;
5746
5747 case dUNLOCKED:
5748 362 doortype=dt_olck;
5749 362 break;
5750
5751 case dSHUTTER:
5752
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5753 {
5754 doortype=dt_osht;
5755 get_screen_state(cur_screen).open_doors = -4;
5756 break;
5757 }
5758
5759 [[fallthrough]];
5760 case d1WAYSHUTTER:
5761 1757 doortype=dt_shut;
5762 1757 break;
5763
5764 case dOPENSHUTTER:
5765 3958 doortype=dt_osht;
5766 3958 break;
5767
5768 case dBOSS:
5769 4 doortype=dt_boss;
5770 4 break;
5771
5772 case dOPENBOSS:
5773 51 doortype=dt_obos;
5774 51 break;
5775
5776 case dBOMBED:
5777 231 doortype=dt_bomb;
5778 231 break;
5779
5780 default:
5781 return;
5782 }
5783
5784
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5785 {
5786 case up:
5787
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5788 {
5789 case dBOMBED:
5790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5791 {
5792 69 over_door(scr,dest,39,side,0,0);
5793 69 }
5794 [[fallthrough]];
5795 default:
5796 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5797 1860 break;
5798 }
5799
5800 1860 break;
5801
5802 case down:
5803
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5804 {
5805 case dBOMBED:
5806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5807 {
5808 39 over_door(scr,dest,135,side,0,0);
5809 39 }
5810 [[fallthrough]];
5811 default:
5812 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5813 1357 break;
5814 }
5815
5816 1357 break;
5817
5818 case left:
5819
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5820 {
5821 case dBOMBED:
5822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5823 {
5824 51 over_door(scr,dest,66,side,0,0);
5825 51 }
5826 [[fallthrough]];
5827 default:
5828 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5829 1514 break;
5830 }
5831
5832 1514 break;
5833
5834 case right:
5835
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5836 {
5837 case dBOMBED:
5838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5839 {
5840 72 over_door(scr,dest,77,side,0,0);
5841 72 }
5842 [[fallthrough]];
5843 default:
5844 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5845 1682 break;
5846 }
5847
5848 1682 break;
5849 }
5850 6504 }
5851
5852 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5853 {
5854
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5855 {
5856 586 putcombo(dest,x, y, combo, cset);
5857 586 }
5858 586 }
5859
5860 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5861 {
5862
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5863 {
5864 219 overcombo(dest,x, y, combo, cset);
5865 219 }
5866 293 }
5867
5868 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5869 {
5870 125 int32_t d = scr->door_combo_set;
5871
5872
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5873 {
5874 case up:
5875 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5876 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5877 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5878 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5879 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5880 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5881 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5882 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5883 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5884 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5885 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5886 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5887 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5888 43 DoorComboSets[d].bombdoorcombo_u[0],
5889 43 DoorComboSets[d].bombdoorcset_u[0]);
5890 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5891 43 DoorComboSets[d].bombdoorcombo_u[1],
5892 43 DoorComboSets[d].bombdoorcset_u[1]);
5893 43 break;
5894
5895 case down:
5896 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5897 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5898 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5899 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5900 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5901 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5902 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5903 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5904 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5905 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5906 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5907 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5908 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5909 39 DoorComboSets[d].bombdoorcombo_d[0],
5910 39 DoorComboSets[d].bombdoorcset_d[0]);
5911 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5912 39 DoorComboSets[d].bombdoorcombo_d[1],
5913 39 DoorComboSets[d].bombdoorcset_d[1]);
5914 39 break;
5915
5916 case left:
5917 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5918 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5919 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5920 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5921 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5922 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5923 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5924 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5925 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5926 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5927 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5928 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5929 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5930 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5931 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5932 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5933 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5934 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5935 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5936 6 DoorComboSets[d].bombdoorcombo_l[0],
5937 6 DoorComboSets[d].bombdoorcset_l[0]);
5938 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5939 6 DoorComboSets[d].bombdoorcombo_l[1],
5940 6 DoorComboSets[d].bombdoorcset_l[1]);
5941 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5942 6 DoorComboSets[d].bombdoorcombo_l[2],
5943 6 DoorComboSets[d].bombdoorcset_l[2]);
5944 6 break;
5945
5946 case right:
5947 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5948 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5949 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5950 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5951 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5952 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5953 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5954 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5955 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5956 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5957 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5958 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5959 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5960 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5961 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5962 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5963 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5964 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5965 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5966 37 DoorComboSets[d].bombdoorcombo_r[0],
5967 37 DoorComboSets[d].bombdoorcset_r[0]);
5968 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5969 37 DoorComboSets[d].bombdoorcombo_r[1],
5970 37 DoorComboSets[d].bombdoorcset_r[1]);
5971 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5972 37 DoorComboSets[d].bombdoorcombo_r[2],
5973 37 DoorComboSets[d].bombdoorcset_r[2]);
5974 37 break;
5975 }
5976 125 }
5977
5978 5530227 void openshutters(mapscr* scr)
5979 {
5980 5530227 bool opened_door = false;
5981
2/2
✓ Branch 0 taken 5530227 times.
✓ Branch 1 taken 22120908 times.
27651135 for(int32_t i=0; i<4; i++)
5982
2/2
✓ Branch 0 taken 22116950 times.
✓ Branch 1 taken 3958 times.
22124866 if(scr->door[i]==dSHUTTER)
5983 {
5984 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5985 3958 scr->door[i]=dOPENSHUTTER;
5986 3958 opened_door = true;
5987 3958 }
5988
5989 5530227 auto& combo_cache = combo_caches::shutter;
5990 2222626133 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5991
3/4
✓ Branch 0 taken 2215173305 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1922594 times.
✗ Branch 3 not taken.
2217095906 if (!combo_cache.minis[handle.data()].shutter)
5992 2217095899 return;
5993
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5994 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5995 });
5996 2217095906 });
5997
5998
2/2
✓ Branch 0 taken 5527496 times.
✓ Branch 1 taken 2731 times.
5530227 if(opened_door)
5999 2731 sfx(WAV_DOOR);
6000 5530227 }
6001
6002 15715802 void clear_darkroom_bitmaps()
6003 {
6004 15715802 clear_to_color(darkscr_bmp, game->get_darkscr_color());
6005 15715802 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
6006 15715802 }
6007
6008 16743904 bool is_dark(const mapscr* scr)
6009 {
6010 16743904 bool dark = scr->flags&fDARK;
6011
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16740182 times.
16743904 if (region_is_lit) return !dark;
6012 16740182 return dark;
6013 16743904 }
6014
6015 53189 bool scrolling_is_dark(const mapscr* scr)
6016 {
6017 53189 bool dark = scr->flags&fDARK;
6018
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 53187 times.
53189 if (scrolling_region_is_lit) return !dark;
6019 53187 return dark;
6020 53189 }
6021
6022 38436 bool is_any_dark()
6023 {
6024 38436 bool dark = false;
6025 78128 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6026 39692 dark |= (bool)(is_dark(scr));
6027 39692 });
6028 38436 return dark;
6029 }
6030
6031
3/4
✓ Branch 0 taken 2996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2568 times.
✓ Branch 3 taken 428 times.
2996 static mapscr prev_origin_scrs[7];
6032 428 static std::set<int> loadscr_ffc_script_ids_to_remove;
6033
6034 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6035 {
6036 mapscr* base_scr = screens[0];
6037 mapscr* previous_scr = &prev_origin_scrs[0];
6038
6039 for (int i = 0; i < 176; i++)
6040 {
6041 if (base_scr->data[i] == 0)
6042 {
6043 base_scr->data[i] = previous_scr->data[i];
6044 base_scr->sflag[i] = previous_scr->sflag[i];
6045 base_scr->cset[i] = previous_scr->cset[i];
6046 }
6047 }
6048
6049 for (int i = 0; i < 6; i++)
6050 {
6051 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6052 {
6053 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6054 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6055
6056 for (int j = 0; j < 176; j++)
6057 {
6058 if (TheMaps[lm].data[j] == 0)
6059 {
6060 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6061 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6062 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6063 }
6064 }
6065 }
6066 }
6067
6068 for (int i = 1; i <= 6; i++)
6069 {
6070 mapscr* scr = screens[i];
6071 previous_scr = &prev_origin_scrs[i];
6072
6073 if (scr->layermap[i] > 0)
6074 {
6075 for (int y = 0; y < 11; y++)
6076 {
6077 for (int x = 0; x < 16; x++)
6078 {
6079 int c = y*16+x;
6080
6081 if (scr->data[c]==0)
6082 {
6083 scr->data[c] = previous_scr->data[c];
6084 scr->sflag[c] = previous_scr->sflag[c];
6085 scr->cset[c] = previous_scr->cset[c];
6086 }
6087 }
6088 }
6089 }
6090 }
6091 }
6092
6093 38776 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6094 {
6095 38776 std::vector<mapscr*> screens;
6096
6097
1/2
✓ Branch 0 taken 38776 times.
✗ Branch 1 not taken.
38776 const mapscr* source = get_canonical_scr(cur_map, screen);
6098
2/4
✓ Branch 0 taken 38776 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38776 times.
✗ Branch 3 not taken.
38776 mapscr* base_scr = new mapscr(*source);
6099 38776 temporary_screens[screen*7] = base_scr;
6100
1/2
✓ Branch 0 taken 38776 times.
✗ Branch 1 not taken.
38776 screens.push_back(base_scr);
6101
6102 38776 base_scr->valid |= mVALID; // layer 0 is always valid
6103
6104
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37532 times.
38776 if (screen == cur_screen)
6105 37532 origin_scr = base_scr;
6106
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37532 times.
38776 if (screen == Hero.current_screen)
6107 37532 hero_scr = prev_hero_scr = base_scr;
6108
6109
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 38632 times.
38776 if (source->script > 0)
6110
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6111
6112
2/2
✓ Branch 0 taken 38776 times.
✓ Branch 1 taken 232656 times.
271432 for (int i = 0; i < 6; i++)
6113 {
6114
2/2
✓ Branch 0 taken 176179 times.
✓ Branch 1 taken 56477 times.
232656 if(source->layermap[i]>0)
6115 {
6116
3/6
✓ Branch 0 taken 56477 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56477 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56477 times.
✗ Branch 5 not taken.
56477 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6117 56477 layer_scr->map = cur_map;
6118 56477 layer_scr->screen = screen;
6119 56477 layer_scr->valid |= mVALID;
6120
1/2
✓ Branch 0 taken 56477 times.
✗ Branch 1 not taken.
56477 screens.push_back(layer_scr);
6121 56477 }
6122 else
6123 {
6124
2/4
✓ Branch 0 taken 176179 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176179 times.
✗ Branch 3 not taken.
176179 mapscr* layer_scr = new mapscr();
6125 176179 layer_scr->map = cur_map;
6126 176179 layer_scr->screen = screen;
6127
1/2
✓ Branch 0 taken 176179 times.
✗ Branch 1 not taken.
176179 screens.push_back(layer_scr);
6128 }
6129 232656 temporary_screens[screen*7+i+1] = screens[i+1];
6130 232656 }
6131
6132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38776 times.
38776 if (screen_overlay)
6133 handle_screen_overlay(screens);
6134
6135
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 38631 times.
38776 if (ffc_overlay)
6136 {
6137 145 mapscr* previous_scr = &prev_origin_scrs[0];
6138
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 int num_ffcs = previous_scr->numFFC();
6139
2/2
✓ Branch 0 taken 4640 times.
✓ Branch 1 taken 145 times.
4785 for (int i = 0; i < num_ffcs; i++)
6140 {
6141
2/2
✓ Branch 0 taken 4365 times.
✓ Branch 1 taken 275 times.
4640 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6142 {
6143
2/4
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
275 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6144 275 ffc.screen_spawned = screen;
6145
6146
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6147
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6149 {
6150 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6151 }
6152 275 }
6153 4640 }
6154 145 }
6155
6156
1/2
✓ Branch 0 taken 38776 times.
✗ Branch 1 not taken.
2252358 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6157
1/2
✓ Branch 0 taken 38776 times.
✗ Branch 1 not taken.
38776 int num_ffcs = base_scr->numFFC();
6158
2/2
✓ Branch 0 taken 1106791 times.
✓ Branch 1 taken 38776 times.
1145567 for (word i = 0; i < num_ffcs; i++)
6159 {
6160 1106791 base_scr->ffcs[i].screen_spawned = screen;
6161 1106791 base_scr->ffcs[i].x += offx;
6162 1106791 base_scr->ffcs[i].y += offy;
6163 1106791 }
6164 38776 }
6165
6166 38776 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6167 {
6168 38776 mapscr* base_scr = get_scr(screen);
6169 38776 int mi = mapind(cur_map, screen);
6170
6171 // Apply perm secrets, if applicable.
6172
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 27256 times.
38776 if (canPermSecret(dmap, screen))
6173 {
6174
2/2
✓ Branch 0 taken 24350 times.
✓ Branch 1 taken 2906 times.
27256 if(game->maps[mi] & mSECRET) // if special stuff done before
6175 {
6176 2906 reveal_hidden_stairs(base_scr, screen, false);
6177 2906 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6178 2906 }
6179
2/2
✓ Branch 0 taken 27253 times.
✓ Branch 1 taken 3 times.
27256 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6180 {
6181
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6182 {
6183 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6184
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6185 {
6186 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6187
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6188 {
6189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6190 {
6191 3 layer_scr->data[pos] += 1;
6192 3 }
6193 3 }
6194 3696 }
6195 21 }
6196 3 }
6197 27256 }
6198
6199 38776 auto screen_handles = create_screen_handles(base_scr);
6200
6201 38776 int destlvl = DMaps[dmap].level;
6202 38776 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6203 38776 toggle_gswitches_load(screen_handles);
6204
6205 38776 bool should_check_for_state_things = (screen < 0x80);
6206
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 37869 times.
38776 if (should_check_for_state_things)
6207 {
6208
2/2
✓ Branch 0 taken 37435 times.
✓ Branch 1 taken 434 times.
37869 if (game->maps[mi]&mLOCKBLOCK)
6209 434 remove_lockblocks(screen_handles);
6210
2/2
✓ Branch 0 taken 37780 times.
✓ Branch 1 taken 89 times.
37869 if (game->maps[mi]&mBOSSLOCKBLOCK)
6211 89 remove_bosslockblocks(screen_handles);
6212
2/2
✓ Branch 0 taken 37701 times.
✓ Branch 1 taken 168 times.
37869 if (game->maps[mi]&mCHEST)
6213 168 remove_chests(screen_handles);
6214
1/2
✓ Branch 0 taken 37869 times.
✗ Branch 1 not taken.
37869 if (game->maps[mi]&mLOCKEDCHEST)
6215 remove_lockedchests(screen_handles);
6216
2/2
✓ Branch 0 taken 37858 times.
✓ Branch 1 taken 11 times.
37869 if (game->maps[mi]&mBOSSCHEST)
6217 11 remove_bosschests(screen_handles);
6218
6219 37869 clear_xdoors_mi(screen_handles, mi, true);
6220 37869 clear_xstatecombos_mi(screen_handles, mi, true);
6221 37869 }
6222
6223 // check doors
6224
2/2
✓ Branch 0 taken 27255 times.
✓ Branch 1 taken 11521 times.
38776 if (isdungeon(dmap, screen))
6225 {
6226
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6227 {
6228 46084 int32_t door=base_scr->door[i];
6229
6230
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6231 {
6232 case d1WAYSHUTTER:
6233 case dSHUTTER:
6234
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6235 {
6236 1694 base_scr->door[i]=dOPENSHUTTER;
6237 1694 }
6238
6239 5303 get_screen_state(screen).open_doors = -4;
6240 5303 break;
6241
6242 case dLOCKED:
6243
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6244 {
6245 1473 base_scr->door[i]=dUNLOCKED;
6246 1473 }
6247
6248 2372 break;
6249
6250 case dBOSS:
6251
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6252 {
6253 62 base_scr->door[i]=dOPENBOSS;
6254 62 }
6255
6256 230 break;
6257
6258 case dBOMB:
6259
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6260 {
6261 1087 base_scr->door[i]=dBOMBED;
6262 1087 }
6263
6264 1704 break;
6265 }
6266
6267 46084 update_door(base_scr, i, base_scr->door[i]);
6268
6269
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6270 {
6271 5303 base_scr->door[i]=door;
6272 5303 }
6273 46084 }
6274 11521 }
6275
6276
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 38637 times.
38776 if (!(base_scr->flags3 & fCYCLEONINIT))
6277 38637 return;
6278
6279
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 973 times.
1112 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6280 {
6281
4/4
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 451 times.
973 if (j<0 || base_scr->layermap[j] > 0)
6282 {
6283 522 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6284
3/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 383 times.
522 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6285 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6286
6287
2/2
✓ Branch 0 taken 91872 times.
✓ Branch 1 taken 522 times.
92394 for(int32_t i=0; i<176; ++i)
6288 {
6289 91872 int32_t c=layerscreen->data[i];
6290
6291 // New screen flag: Cycle Combos At Screen Init
6292
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 91807 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
91872 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6293 {
6294 65 int32_t r = 0;
6295
6296
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6297 {
6298 84 newcombo const& cmb = combobuf[c];
6299 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6301 84 layerscreen->data[i] = cid;
6302
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6304 84 c = layerscreen->data[i];
6305 }
6306 65 }
6307 91872 }
6308 522 }
6309 973 }
6310 38776 }
6311
6312 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6313 //
6314 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6315 // the game, etc...)
6316 //
6317 // Note: for regions, only the initial screen load calls this function. Simply walking between
6318 // screens in the same region does not use this, because every screen in a region is loaded into
6319 // temporary memory up front.
6320 //
6321 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6322 // `special_warp_return_scr`.
6323 //
6324 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6325 // on all layers (but only where the new screen has a 0 combo).
6326 //
6327 // TODO: loadscr should set curdmap, but currently callers do that.
6328 37532 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6329 {
6330 37532 zapp_reporting_set_tag("screen", screen);
6331
2/2
✓ Branch 0 taken 9312 times.
✓ Branch 1 taken 28220 times.
37532 if (destdmap != -1)
6332 9312 zapp_reporting_set_tag("dmap", destdmap);
6333
6334 37532 int32_t orig_destdmap = destdmap;
6335
2/2
✓ Branch 0 taken 9312 times.
✓ Branch 1 taken 28220 times.
37532 if (destdmap < 0) destdmap = cur_dmap;
6336
6337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37532 times.
37532 if (replay_is_active())
6338 {
6339
2/2
✓ Branch 0 taken 28220 times.
✓ Branch 1 taken 9312 times.
37532 if (orig_destdmap != -1)
6340 {
6341
2/2
✓ Branch 0 taken 8241 times.
✓ Branch 1 taken 1071 times.
9312 if (strlen(DMaps[orig_destdmap].name) > 0)
6342 {
6343
1/2
✓ Branch 0 taken 8241 times.
✗ Branch 1 not taken.
8241 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6344 8241 }
6345 else
6346 {
6347
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6348 }
6349 9312 }
6350 37532 replay_step_comment_loadscr(screen);
6351
6352 // Reset the rngs and frame count so that recording steps can be modified without impacting
6353 // behavior of later screens.
6354 37532 replay_sync_rng();
6355 37532 }
6356
6357
2/2
✓ Branch 0 taken 1754088 times.
✓ Branch 1 taken 37532 times.
1791620 for (auto& state : get_screen_states())
6358 1754088 state.second.triggered_secrets = false;
6359 37532 slopes.clear();
6360 37532 Hero.clear_platform_ffc();
6361 37532 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6362 37532 clear_darkroom_bitmaps();
6363 37532 msgscr = nullptr;
6364
6365
2/2
✓ Branch 0 taken 52508672 times.
✓ Branch 1 taken 37532 times.
52546204 for (word x=0; x<animated_combos; x++)
6366 {
6367
2/2
✓ Branch 0 taken 21102420 times.
✓ Branch 1 taken 31406252 times.
52508672 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6368 {
6369 21102420 combobuf[animated_combo_table4[x][0]].aclk = 0;
6370 21102420 }
6371 52508672 }
6372 37532 reset_combo_animations2();
6373 37532 region_is_lit = false;
6374
6375 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6376 // of the new ones.
6377 37532 bool origin_ffc_overlay = false;
6378
2/2
✓ Branch 0 taken 1171 times.
✓ Branch 1 taken 36361 times.
37532 if (origin_scr)
6379 {
6380
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36359 times.
36361 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6381 {
6382 36359 int c = origin_scr->numFFC();
6383
2/2
✓ Branch 0 taken 36214 times.
✓ Branch 1 taken 1040673 times.
1076887 for (int i = 0; i < c; i++)
6384 {
6385
2/2
✓ Branch 0 taken 1040528 times.
✓ Branch 1 taken 145 times.
1040673 if (origin_scr->ffcs[i].flags&ffc_carryover)
6386 {
6387 145 origin_ffc_overlay = true;
6388 145 break;
6389 }
6390 1040528 }
6391 36359 }
6392
6393
3/4
✓ Branch 0 taken 36361 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 36216 times.
36361 if (origin_screen_overlay || origin_ffc_overlay)
6394 {
6395
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 145 times.
1160 for (int i = 0; i <= 6; i++)
6396 {
6397 1015 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6398
1/2
✓ Branch 0 taken 1015 times.
✗ Branch 1 not taken.
1015 if (prev_scr)
6399 1015 prev_origin_scrs[i] = *prev_scr;
6400 else
6401 prev_origin_scrs[i] = {};
6402 1015 }
6403 145 }
6404 36361 }
6405
6406 // When loading a new screen, all previous FFC scripts end, with one exception.
6407 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6408 // them, but scripts that need their data to persist will be removed.
6409 37532 loadscr_ffc_script_ids_to_remove.clear();
6410
2/2
✓ Branch 0 taken 83201472 times.
✓ Branch 1 taken 37532 times.
83239004 for (auto& key : scriptEngineDatas | std::views::keys)
6411 {
6412
2/2
✓ Branch 0 taken 82070519 times.
✓ Branch 1 taken 1130953 times.
83201472 if (key.first == ScriptType::FFC)
6413 1130953 loadscr_ffc_script_ids_to_remove.insert(key.second);
6414 }
6415
6416 37532 load_region(destdmap, screen);
6417
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36625 times.
37532 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6418 37532 Hero.current_screen = screen;
6419
6420 37532 cpos_clear_all();
6421 37532 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6422 37532 FFCore.clear_combo_scripts();
6423
6424
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37368 times.
37532 if (is_in_scrolling_region())
6425 {
6426
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6427 {
6428
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6429 {
6430
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6431
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6432 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6433 1408 }
6434 20992 }
6435 164 }
6436 else
6437 {
6438 37368 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6439 }
6440
6441 37532 prepare_current_region_handles();
6442
6443
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37368 times.
37532 if (is_in_scrolling_region())
6444 {
6445
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6446 {
6447
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6448 {
6449 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6450 1408 }
6451 20992 }
6452 164 }
6453 else
6454 {
6455 37368 load_a_screen_and_layers_post(destdmap, screen, ldir);
6456 }
6457
6458 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6459
2/2
✓ Branch 0 taken 36625 times.
✓ Branch 1 taken 907 times.
37532 if (screen >= 0x80)
6460
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6461
6462 37532 update_slope_comboposes();
6463 37532 cpos_force_update();
6464 37532 trig_trigger_groups();
6465
6466
2/2
✓ Branch 0 taken 1130678 times.
✓ Branch 1 taken 37532 times.
1168210 for (int index : loadscr_ffc_script_ids_to_remove)
6467 {
6468 // Note: ideally would use "destroySprite", but during scrolling the previous
6469 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6470 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6471 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6472 // is used instead.
6473 //
6474 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6475 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6476 // it is called above when "load_region" calls "clear_temporary_screens".
6477 1130678 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6478 }
6479
6480 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6481 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6482 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6483 // It is up to the quest designer to make their subscreen be actually transparent.
6484 //
6485 // When not in "extended height mode" (otherwise 56 is 0):
6486 // - playing_field_offset: 56, but changes during earthquakes
6487 // - original_playing_field_offset: always 56
6488 //
6489 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6490 // - yofs of sprites
6491 // - bitmap y offsets in draw_screen
6492 // - drawing offsets for putscr, do_layer
6493 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6494 // - lots more
6495 //
6496 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6497
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 37390 times.
37532 if (is_extended_height_mode())
6498 {
6499 142 playing_field_offset = 0;
6500 142 original_playing_field_offset = 0;
6501 // A few sprites exist as globals, so we must manually reset them.
6502 142 Hero.yofs = 0;
6503 142 mblock2.yofs = 0;
6504 142 }
6505 else
6506 {
6507 37390 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6508 37390 original_playing_field_offset = 56;
6509 }
6510 37532 is_any_room_dark = is_any_dark();
6511
6512 37532 game->load_portal();
6513 37532 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6514
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 37497 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
37532 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6515 {
6516 delete Hero.lift_wpn;
6517 Hero.lift_wpn = nullptr;
6518 }
6519
6520 37532 enemy_spawning_has_checked_been_here = false;
6521 37532 markBmap(-1, Hero.current_screen);
6522 37532 Hero.maybe_begin_advanced_maze();
6523 37532 }
6524
6525 // Don't use this directly! Use `loadscr` instead.
6526 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6527 {
6528
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6529
6530 907 mapscr previous_scr = *special_warp_return_scr;
6531 907 mapscr* scr = special_warp_return_scr;
6532
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6533
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6534
6535
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6536 {
6537
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6538
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6539 else
6540
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6541 5442 }
6542
6543 907 scr->valid |= mVALID; //layer 0 is always valid
6544
6545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6546 {
6547 scr->script = source->script;
6548 for ( int32_t q = 0; q < 8; q++ )
6549 {
6550 scr->screeninitd[q] = source->screeninitd[q];
6551 }
6552 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6553 }
6554 else
6555 {
6556 907 scr->script = 0;
6557 }
6558
6559
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6560 {
6561 for(int32_t c=0; c< 176; ++c)
6562 {
6563 if(scr->data[c]==0)
6564 {
6565 scr->data[c]=previous_scr.data[c];
6566 scr->sflag[c]=previous_scr.sflag[c];
6567 scr->cset[c]=previous_scr.cset[c];
6568 }
6569 }
6570
6571 for(int32_t i=0; i<6; i++)
6572 {
6573 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6574 {
6575 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6576 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6577
6578 for(int32_t c=0; c< 176; ++c)
6579 {
6580 if(TheMaps[lm].data[c]==0)
6581 {
6582 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6583 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6584 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6585 }
6586 }
6587 }
6588 }
6589 }
6590
6591
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6592
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6593
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6594 {
6595 28993 scr->ffcs[i].screen_spawned = screen;
6596
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6597
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6598 28993 }
6599
6600 907 int mi = mapind(cur_map, screen);
6601
6602 // Apply perm secrets, if applicable.
6603
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6604 {
6605
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6606 {
6607
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6608
6609
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6610
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6611 204 bool do_replay_comment = true;
6612 204 bool from_active_screen = false;
6613
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6614 204 }
6615
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6616 {
6617 for (int layer = 0; layer <= 6; layer++)
6618 {
6619 mapscr* tscr = &special_warp_return_scrs[layer];
6620 for (int pos = 0; pos < 176; pos++)
6621 {
6622 newcombo const* cmb = &combobuf[tscr->data[pos]];
6623 if(cmb->type == cLIGHTTARGET)
6624 {
6625 if(!(cmb->usrflags&cflag1)) //Unlit version
6626 {
6627 tscr->data[pos] += 1;
6628 }
6629 }
6630 }
6631 }
6632 }
6633 536 }
6634
6635 screen_handles_t screen_handles;
6636
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6637
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6638
6639
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6640
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6641
6642
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6643 {
6644
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6645 5 }
6646
6647
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6648 {
6649
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6650 1 }
6651
6652
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6653 {
6654 remove_chests(screen_handles);
6655 }
6656
6657
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6658 {
6659 remove_lockedchests(screen_handles);
6660 }
6661
6662
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6663 {
6664 remove_bosschests(screen_handles);
6665 }
6666
6667
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6668
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6669
6670 // check doors
6671
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6672 {
6673
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6674 {
6675 1484 int32_t door=scr->door[i];
6676
6677
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6678 {
6679 case d1WAYSHUTTER:
6680 case dSHUTTER:
6681 if ((ldir^1)==i && screen == home_screen)
6682 {
6683 scr->door[i]=dOPENSHUTTER;
6684 }
6685
6686 get_screen_state(screen).open_doors = -4;
6687 105 break;
6688
6689 case dLOCKED:
6690
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6691 {
6692 80 scr->door[i]=dUNLOCKED;
6693 80 }
6694
6695 91 break;
6696
6697 case dBOSS:
6698
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6699 {
6700 5 scr->door[i]=dOPENBOSS;
6701 5 }
6702
6703 9 break;
6704
6705 case dBOMB:
6706
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6707 {
6708 51 scr->door[i]=dBOMBED;
6709 51 }
6710
6711 89 break;
6712 }
6713
6714
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6715
6716
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6717 {
6718 105 scr->door[i]=door;
6719 105 }
6720 1484 }
6721 371 }
6722
6723
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6724 {
6725
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6726 {
6727
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6728 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6729
6730
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6731 {
6732 226830 int32_t c=layerscreen->data[i];
6733
6734 // New screen flag: Cycle Combos At Screen Init
6735
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6736 {
6737 210 int32_t r = 0;
6738
6739
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6740 {
6741 newcombo const& cmb = combobuf[c];
6742 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6743 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6744 layerscreen->data[i] = cid;
6745 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6746 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6747 c = layerscreen->data[i];
6748 }
6749 }
6750 227040 }
6751 1500 }
6752 6349 }
6753 1537 }
6754
6755 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6756 // instead returns an array of mapscr.
6757 // Used to draw/save the map.
6758 47360 std::array<mapscr, 7> loadscr2(int32_t screen)
6759 {
6760 47360 std::array<mapscr, 7> scrs;
6761 47360 mapscr* scr = &scrs[0];
6762
6763
2/2
✓ Branch 0 taken 66834661 times.
✓ Branch 1 taken 47360 times.
66882021 for(word x=0; x<animated_combos; x++)
6764 {
6765
2/2
✓ Branch 0 taken 33899045 times.
✓ Branch 1 taken 32935616 times.
66834661 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6766 {
6767 32935616 combobuf[animated_combo_table4[x][0]].aclk=0;
6768 32935616 }
6769 66834661 }
6770
6771
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 const mapscr* source = get_canonical_scr(cur_map, screen);
6772
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!source->is_valid())
6773 {
6774 scrs[0].valid = 0;
6775 return scrs;
6776 }
6777
6778
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 *scr = *get_canonical_scr(cur_map, screen);
6779
2/2
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
331520 for (int i = 1; i <= 6; i++)
6780 {
6781
2/2
✓ Branch 0 taken 209501 times.
✓ Branch 1 taken 74659 times.
284160 if (scr->layermap[i-1] > 0)
6782
2/4
✓ Branch 0 taken 74659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74659 times.
✗ Branch 3 not taken.
74659 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6783 else
6784
2/4
✓ Branch 0 taken 209501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209501 times.
✗ Branch 3 not taken.
209501 scrs[i] = {};
6785 284160 }
6786
6787 screen_handles_t screen_handles;
6788
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i < 7; i++)
6789
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6790
6791 47360 int mi = mapind(cur_map, screen);
6792
6793
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if(canPermSecret(-1,screen))
6794 {
6795
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6344 times.
✓ Branch 3 taken 40962 times.
47306 if(game->maps[mi]&mSECRET) // if special stuff done before
6796 {
6797
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 reveal_hidden_stairs(scr, screen, false);
6798 6344 bool from_active_screen = false;
6799 6344 bool do_replay_comment = true;
6800
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6801 6344 }
6802
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47289 times.
✓ Branch 3 taken 17 times.
47306 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6803 {
6804
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6805 {
6806 119 mapscr* tscr = &scrs[layer];
6807
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6808 {
6809 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6810
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6811 {
6812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6813 {
6814 17 tscr->data[pos] += 1;
6815 17 }
6816 17 }
6817 20944 }
6818 119 }
6819 17 }
6820 47306 }
6821
6822
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 271 times.
✓ Branch 3 taken 47089 times.
47360 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6823 {
6824
1/2
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
271 remove_lockblocks(screen_handles);
6825 271 }
6826
6827
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 47359 times.
47360 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6828 {
6829
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6830 1 }
6831
6832
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 47254 times.
47360 if(game->maps[mi]&mCHEST) // if special stuff done before
6833 {
6834
1/2
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
106 remove_chests(screen_handles);
6835 106 }
6836
6837
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 47336 times.
47360 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6838 {
6839
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6840 24 }
6841
6842
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47360 times.
47360 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6843 {
6844 remove_bosschests(screen_handles);
6845 }
6846
6847
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xdoors(screen_handles);
6848
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xstatecombos(screen_handles);
6849
6850 // check doors
6851
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if (isdungeon(screen))
6852 {
6853
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6854 {
6855 216 int32_t door=scr->door[i];
6856 216 bool putit=true;
6857
6858
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6859 {
6860 case d1WAYSHUTTER:
6861 case dSHUTTER:
6862 61 break;
6863
6864 case dLOCKED:
6865
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6866 {
6867 12 scr->door[i]=dUNLOCKED;
6868 12 }
6869
6870 12 break;
6871
6872 case dBOSS:
6873
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6874 {
6875 scr->door[i]=dOPENBOSS;
6876 }
6877
6878 4 break;
6879
6880 case dBOMB:
6881 if(game->maps[mi]&(mDOOR_UP<<i))
6882 {
6883 scr->door[i]=dBOMBED;
6884 }
6885
6886 break;
6887 }
6888
6889
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6890 {
6891
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6892 216 }
6893
6894
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6895 {
6896 61 scr->door[i]=door;
6897 61 }
6898 216 }
6899 54 }
6900
6901
2/2
✓ Branch 0 taken 331520 times.
✓ Branch 1 taken 47360 times.
378880 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6902 {
6903
4/4
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
✓ Branch 2 taken 74659 times.
✓ Branch 3 taken 209501 times.
331520 if (j < 0 || scr->layermap[j] > 0)
6904 {
6905
2/2
✓ Branch 0 taken 74659 times.
✓ Branch 1 taken 47360 times.
122019 mapscr *layerscreen= (j<0 ? scr
6906 74659 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6907
6908
2/2
✓ Branch 0 taken 21475344 times.
✓ Branch 1 taken 122019 times.
21597363 for(int32_t i=0; i<176; ++i)
6909 {
6910 21475344 int32_t c=layerscreen->data[i];
6911
6912 // New screen flag: Cycle Combos At Screen Init
6913
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21475344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
21475344 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6914 {
6915 int32_t r = 0;
6916
6917 while(combobuf[c].can_cycle() && r++ < 10)
6918 {
6919 newcombo const& cmb = combobuf[c];
6920 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6921 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6922 layerscreen->data[i] = cid;
6923 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6924 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6925 c = layerscreen->data[i];
6926 }
6927 }
6928 21475344 }
6929 122019 }
6930 331520 }
6931
6932 47360 return scrs;
6933
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 }
6934
6935 19767692 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6936 {
6937 // This is a bogus value while screenscrolling == true, but that's ok
6938 // because it is only used to calculate the rpos, and during screenscrolling
6939 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6940 // is always the same no matter the value of scr.
6941 19767692 int screen = get_screen_for_world_xy(x, y);
6942
6943 19767692 x -= viewport.x;
6944 19767692 y -= viewport.y;
6945
6946
3/6
✓ Branch 0 taken 19767692 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19767692 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19767692 times.
19767692 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6947 {
6948 rectfill(dest,x,y,x+255,y+175,0);
6949 return;
6950 }
6951
6952 39387917 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6953
2/2
✓ Branch 0 taken 19620225 times.
✓ Branch 1 taken 147467 times.
19767692 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6954
2/2
✓ Branch 0 taken 243651 times.
✓ Branch 1 taken 19376574 times.
19620225 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6955
6956 int start_x, end_x, start_y, end_y;
6957 19767692 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6958
2/2
✓ Branch 0 taken 19767692 times.
✓ Branch 1 taken 210543286 times.
230310978 for (int cy = start_y; cy < end_y; cy++)
6959 {
6960
2/2
✓ Branch 0 taken 3196690802 times.
✓ Branch 1 taken 210543286 times.
3407234088 for (int cx = start_x; cx < end_x; cx++)
6961 {
6962 3196690802 int i = cx + cy*16;
6963
2/2
✓ Branch 0 taken 374288294 times.
✓ Branch 1 taken 2822402508 times.
3196690802 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6964 3196690802 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6965 3196690802 }
6966 210543286 }
6967 19767692 }
6968
6969 16133788 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6970 {
6971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
16133788 if (!show_layers[0])
6972 {
6973 return;
6974 }
6975
6976 16133788 x -= viewport.x;
6977 16133788 y -= viewport.y;
6978
6979
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6980 16270106 mapscr* scr = screen_handles[0].base_scr;
6981
1/2
✓ Branch 0 taken 16270106 times.
✗ Branch 1 not taken.
16270106 if (!scr->is_valid())
6982 return;
6983
6984
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 16146695 times.
16270106 if(scr->door[0]==dBOMBED)
6985 {
6986 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6987 123411 }
6988
6989
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 16126997 times.
16270106 if(scr->door[1]==dBOMBED)
6990 {
6991 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6992 143109 }
6993
6994
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 16114244 times.
16270106 if(scr->door[2]==dBOMBED)
6995 {
6996 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6997 155862 }
6998
6999
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 16137817 times.
16270106 if(scr->door[3]==dBOMBED)
7000 {
7001 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
7002 132289 }
7003 16270106 });
7004 16133788 }
7005
7006 3497586 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
7007 {
7008
2/4
✓ Branch 0 taken 3497586 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3497586 times.
✗ Branch 3 not taken.
3497586 if (!scr->is_valid() || !show_layers[0])
7009 return;
7010
7011 3497586 x -= viewport.x;
7012 3497586 y -= viewport.y;
7013
7014
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3459930 times.
3497586 if(scr->door[0]==dBOMBED)
7015 {
7016 37656 over_door(scr,dest,39,up,x,y);
7017 37656 }
7018
7019
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3461091 times.
3497586 if(scr->door[1]==dBOMBED)
7020 {
7021 36495 over_door(scr,dest,135,down,x,y);
7022 36495 }
7023
7024
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3457146 times.
3497586 if(scr->door[2]==dBOMBED)
7025 {
7026 40440 over_door(scr,dest,66,left,x,y);
7027 40440 }
7028
7029
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3460523 times.
3497586 if(scr->door[3]==dBOMBED)
7030 {
7031 37063 over_door(scr,dest,77,right,x,y);
7032 37063 }
7033 3497586 }
7034 262959976 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7035 {
7036
1/2
✓ Branch 0 taken 262959976 times.
✗ Branch 1 not taken.
262959976 if (cmb.dive_under_level)
7037 {
7038 if (standing_z_state <= -cmb.dive_under_level)
7039 return true;
7040 }
7041
7042 262959976 zfix cmb_z, cmb_z_step;
7043
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 262867187 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
262959976 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7044 {
7045 3970 cmb_z = zslongToFix(cmb.attributes[2]);
7046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
7047 3970 }
7048
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 262954023 times.
262956006 else if(cmb.genflags & cflag3)
7049 {
7050 1983 cmb_z = cmb.z_height;
7051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7052 1983 }
7053 262954023 else return false;
7054
7055
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7056 return true;
7057
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7058
7059 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7060 262959976 }
7061 62156303 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7062 {
7063 62156303 return _walkflag(zx,zy,cnt,0_zf);
7064 }
7065
7066 142618532 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7067 {
7068 142618532 int x = zx.getRound(), y = zy.getRound();
7069 142618532 int pos = COMBOPOS(x % 256, y % 176);
7070 142618532 const newcombo& c = combobuf[s0->data[pos]];
7071 142618532 const newcombo& c1 = combobuf[s1->data[pos]];
7072 142618532 const newcombo& c2 = combobuf[s2->data[pos]];
7073
4/4
✓ Branch 0 taken 140526906 times.
✓ Branch 1 taken 2091626 times.
✓ Branch 2 taken 140517446 times.
✓ Branch 3 taken 9460 times.
285467054 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7074
4/4
✓ Branch 0 taken 114995 times.
✓ Branch 1 taken 140632441 times.
✓ Branch 2 taken 2211836 times.
✓ Branch 3 taken 4245 times.
142618532 (iswater_type(c2.type))) && DRIEDLAKE);
7075 142848522 int32_t b=1;
7076
2/2
✓ Branch 0 taken 70427876 times.
✓ Branch 1 taken 72420646 times.
142848522 if(x&8) b<<=2;
7077
2/2
✓ Branch 0 taken 66774840 times.
✓ Branch 1 taken 76073682 times.
142848522 if(y&8) b<<=1;
7078
7079 142848522 int32_t cwalkflag = c.walk;
7080
4/4
✓ Branch 0 taken 142733518 times.
✓ Branch 1 taken 115004 times.
✓ Branch 2 taken 142733354 times.
✓ Branch 3 taken 164 times.
142848522 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7081
8/10
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 142790856 times.
✓ Branch 2 taken 2206612 times.
✓ Branch 3 taken 2149110 times.
✓ Branch 4 taken 2206612 times.
✓ Branch 5 taken 142733354 times.
✓ Branch 6 taken 2206612 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2206612 times.
✗ Branch 9 not taken.
142848358 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7082
2/2
✓ Branch 0 taken 63216551 times.
✓ Branch 1 taken 79516967 times.
142733518 if (s1 != s0)
7083 {
7084
3/4
✓ Branch 0 taken 79516967 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 79516349 times.
✓ Branch 3 taken 618 times.
79516967 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7085
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79504620 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79516349 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7086
2/2
✓ Branch 0 taken 71255 times.
✓ Branch 1 taken 79445094 times.
79516349 else if (c1.type == cBRIDGE)
7087 {
7088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71255 times.
71255 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7089 {
7090 71255 int efflag = (c1.walk & 0xF0)>>4;
7091 71255 int newsolid = (c1.walk & 0xF);
7092 71255 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7093 71255 }
7094 else cwalkflag &= c1.walk;
7095 71255 }
7096
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79433365 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
79445094 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7097 79445094 else cwalkflag |= c1.walk;
7098 79516967 }
7099
2/2
✓ Branch 0 taken 102024027 times.
✓ Branch 1 taken 40709491 times.
142733518 if (s2 != s0)
7100 {
7101
2/4
✓ Branch 0 taken 40709491 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40709491 times.
✗ Branch 3 not taken.
40709491 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7102
7/10
✓ Branch 0 taken 5889 times.
✓ Branch 1 taken 40703602 times.
✓ Branch 2 taken 5889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3735 times.
✓ Branch 5 taken 2154 times.
✓ Branch 6 taken 3735 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3735 times.
40709491 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7103
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 40689031 times.
40705756 else if (c2.type == cBRIDGE)
7104 {
7105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16725 times.
16725 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7106 {
7107 16725 int efflag = (c2.walk & 0xF0)>>4;
7108 16725 int newsolid = (c2.walk & 0xF);
7109 16725 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7110 16725 }
7111 else cwalkflag &= c2.walk;
7112 16725 }
7113
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 40686877 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40689031 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7114 40689031 else cwalkflag |= c2.walk;
7115 40709491 }
7116
7117
4/4
✓ Branch 0 taken 30808240 times.
✓ Branch 1 taken 111925278 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 30807292 times.
142733518 if((cwalkflag&b) && !dried)
7118 30807292 return true;
7119
7120
3/4
✓ Branch 0 taken 111926226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111857036 times.
✓ Branch 3 taken 69190 times.
111926226 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7121
7122 111857036 return false;
7123 142733518 }
7124
7125 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7126 142733518 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7127 {
7128 142733518 int x = zx.getRound(), y = zy.getRound();
7129 142733518 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7130 142733518 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7131 142733518 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7132
2/2
✓ Branch 0 taken 63216551 times.
✓ Branch 1 taken 79516967 times.
142733518 if (!s1->valid) s1 = s0;
7133
2/2
✓ Branch 0 taken 102024027 times.
✓ Branch 1 taken 40709491 times.
142733518 if (!s2->valid) s2 = s0;
7134 142733518 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7135 }
7136
7137 138205641 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7138 {
7139 138205641 int max_x = world_w;
7140 138205641 int max_y = world_h;
7141
2/2
✓ Branch 0 taken 78162904 times.
✓ Branch 1 taken 60042737 times.
138205641 if (!get_qr(qr_LTTPWALK))
7142 {
7143 60042737 max_x -= 7;
7144 60042737 max_y -= 7;
7145 60042737 }
7146
4/4
✓ Branch 0 taken 137933273 times.
✓ Branch 1 taken 272368 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 137850005 times.
138205641 if (x < 0 || y < 0) return false;
7147
2/2
✓ Branch 0 taken 323548 times.
✓ Branch 1 taken 137526457 times.
137850005 if (x >= max_x) return false;
7148
3/4
✓ Branch 0 taken 571808 times.
✓ Branch 1 taken 136954649 times.
✓ Branch 2 taken 571808 times.
✗ Branch 3 not taken.
137526457 if (x >= max_x - 8 && cnt == 2) return false;
7149
2/2
✓ Branch 0 taken 136972194 times.
✓ Branch 1 taken 554263 times.
137526457 if (y >= max_y) return false;
7150
7151
4/4
✓ Branch 0 taken 30758247 times.
✓ Branch 1 taken 106213947 times.
✓ Branch 2 taken 100452623 times.
✓ Branch 3 taken 5761324 times.
136972194 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7152 138205641 }
7153
7154 105157688 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7155 {
7156 105157688 mapscr* s0 = get_scr_for_world_xy(x, y);
7157 105157688 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7158 105157688 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7159
2/2
✓ Branch 0 taken 57657645 times.
✓ Branch 1 taken 47500043 times.
105157688 if (!s1->valid) s1 = s0;
7160
2/2
✓ Branch 0 taken 24624446 times.
✓ Branch 1 taken 80533242 times.
105157688 if (!s2->valid) s2 = s0;
7161
7162 105157688 int pos = COMBOPOS(x % 256, y % 176);
7163 105157688 const newcombo& c = combobuf[s0->data[pos]];
7164 105157688 const newcombo& c1 = combobuf[s1->data[pos]];
7165 105157688 const newcombo& c2 = combobuf[s2->data[pos]];
7166
4/4
✓ Branch 0 taken 104161984 times.
✓ Branch 1 taken 995704 times.
✓ Branch 2 taken 104160704 times.
✓ Branch 3 taken 1280 times.
210315376 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7167
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104160704 times.
✓ Branch 2 taken 995300 times.
✓ Branch 3 taken 1684 times.
105157688 (iswater_type(c2.type))) && DRIEDLAKE);
7168 105157688 int32_t b=1;
7169
2/2
✓ Branch 0 taken 53216645 times.
✓ Branch 1 taken 51941043 times.
105157688 if(x&8) b<<=2;
7170
2/2
✓ Branch 0 taken 44692803 times.
✓ Branch 1 taken 60464885 times.
105157688 if(y&8) b<<=1;
7171
7172 105157688 int32_t cwalkflag = (c.walk>>4);
7173
2/2
✓ Branch 0 taken 80386473 times.
✓ Branch 1 taken 24771215 times.
105157688 if (layer == 0) cwalkflag = (c1.walk>>4);
7174
2/2
✓ Branch 0 taken 80388149 times.
✓ Branch 1 taken 24769539 times.
105157688 if (layer == 1) cwalkflag = (c2.walk>>4);
7175 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7176
4/4
✓ Branch 0 taken 57657645 times.
✓ Branch 1 taken 47500043 times.
✓ Branch 2 taken 24572336 times.
✓ Branch 3 taken 33085309 times.
105157688 if (s1 != s0 && layer < 0)
7177 {
7178
2/2
✓ Branch 0 taken 24556122 times.
✓ Branch 1 taken 16214 times.
24572336 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7179 24572336 }
7180
4/4
✓ Branch 0 taken 24624446 times.
✓ Branch 1 taken 80533242 times.
✓ Branch 2 taken 17774749 times.
✓ Branch 3 taken 6849697 times.
105157688 if (s2 != s0 && layer < 1)
7181 {
7182
2/2
✓ Branch 0 taken 17762865 times.
✓ Branch 1 taken 11884 times.
17774749 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7183 17774749 }
7184
7185
2/2
✓ Branch 0 taken 104979684 times.
✓ Branch 1 taken 178004 times.
105157688 return (cwalkflag&b) ? !dried : false;
7186 }
7187
7188 105531012 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7189 {
7190 DCHECK(cnt == 0 || cnt == 1);
7191 105531012 int max_x = world_w;
7192 105531012 int max_y = world_h;
7193
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 59697289 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
105531012 if (!get_qr(qr_LTTPWALK) && !notLink)
7194 {
7195 45833723 max_x -= 7;
7196 45833723 max_y -= 7;
7197 45833723 }
7198
4/4
✓ Branch 0 taken 105530260 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 105530056 times.
105531012 if (x < 0 || y < 0) return false;
7199
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 105529240 times.
105530056 if (x >= max_x) return false;
7200
3/4
✓ Branch 0 taken 526426 times.
✓ Branch 1 taken 105002814 times.
✓ Branch 2 taken 526426 times.
✗ Branch 3 not taken.
105529240 if (x >= max_x - 8 && cnt == 2) return false;
7201
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 105157688 times.
105529240 if (y >= max_y) return false;
7202
7203
3/4
✓ Branch 0 taken 104978894 times.
✓ Branch 1 taken 178794 times.
✓ Branch 2 taken 178794 times.
✗ Branch 3 not taken.
105157688 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7204 105531012 }
7205
7206 // used by mapdata->isSolid(x,y) in ZScript
7207 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7208 {
7209 int x = zx.getRound(), y = zy.getRound();
7210 {
7211 int max_x = 256;
7212 int max_y = 176;
7213 if (!get_qr(qr_LTTPWALK))
7214 {
7215 max_x -= 7;
7216 max_y -= 7;
7217 }
7218 if (x < 0 || y < 0) return false;
7219 if (x >= max_x) return false;
7220 if (x >= max_x - 8 && cnt == 2) return false;
7221 if (y >= max_y) return false;
7222 }
7223
7224 const mapscr *s1, *s2;
7225 s1 = s2 = m;
7226
7227 if ( m->layermap[0] > 0 && m->layermap[0] <= map_count )
7228 {
7229 const mapscr* s = get_canonical_scr(m->layermap[0] - 1, m->layerscreen[0]);
7230 if (s->is_valid())
7231 s1 = s;
7232 }
7233
7234 if ( m->layermap[1] > 0 && m->layermap[1] <= map_count )
7235 {
7236 const mapscr* s = get_canonical_scr(m->layermap[1] - 1, m->layerscreen[1]);
7237 if (s->is_valid())
7238 s2 = s;
7239 }
7240
7241 zfix unused;
7242 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7243 }
7244
7245 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7246 {
7247 DCHECK_LAYER_NEG1_INDEX(layer);
7248 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7249 if (!m->is_valid()) return false;
7250 return _walkflag_layer(x, y, cnt, m);
7251 }
7252
7253 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7254 {
7255 int x = zx.getRound(), y = zy.getRound();
7256
7257 if (!get_qr(qr_LTTPWALK))
7258 {
7259 max_x -= 7;
7260 max_y -= 7;
7261 }
7262 if (x < 0 || y < 0) return false;
7263 if (x >= max_x) return false;
7264 if (x >= max_x - 8 && cnt == 2) return false;
7265 if (y >= max_y) return false;
7266
7267 if(!m) return true;
7268
7269 int pos = COMBOPOS(x%256, y%176);
7270 const newcombo* c = &combobuf[m->data[pos]];
7271 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7272 int32_t b=1;
7273
7274 if(x&8) b<<=2;
7275
7276 if(y&8) b<<=1;
7277
7278 if((c->walk&b) && !dried)
7279 return true;
7280
7281 if(cnt==1) return false;
7282
7283 ++pos;
7284
7285 if(!(x&8))
7286 b<<=2;
7287 else
7288 {
7289 c = &combobuf[m->data[pos]];
7290 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7291 b=1;
7292
7293 if(y&8) b<<=1;
7294 }
7295
7296 return (c->walk&b) ? !dried : false;
7297 }
7298
7299 //Only check the given mapscr*, not its layer 1&2
7300 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7301 {
7302 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7303 }
7304
7305 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7306 {
7307 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7308 }
7309
7310 447898 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7311 {
7312 DCHECK_LAYER_NEG1_INDEX(layer);
7313 447898 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7314
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 446136 times.
447898 if (!m->is_valid()) return false;
7315 446136 return _effectflag_layer(x, y, cnt, m, notLink);
7316 447898 }
7317
7318 519213 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7319 {
7320 519213 int max_x = world_w;
7321 519213 int max_y = world_h;
7322
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 469211 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
519213 if (!get_qr(qr_LTTPWALK) && !notLink)
7323 {
7324 max_x -= 7;
7325 max_y -= 7;
7326 }
7327
2/4
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 519213 times.
519213 if (x < 0 || y < 0) return false;
7328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (x >= max_x) return false;
7329
3/4
✓ Branch 0 taken 1342 times.
✓ Branch 1 taken 517871 times.
✓ Branch 2 taken 1342 times.
✗ Branch 3 not taken.
519213 if (x >= max_x - 8 && cnt == 2) return false;
7330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (y >= max_y) return false;
7331
7332
1/2
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
519213 if (!m) return true;
7333
7334 519213 int pos = COMBOPOS(x%256, y%176);
7335 519213 const newcombo* c = &combobuf[m->data[pos]];
7336
3/4
✓ Branch 0 taken 518813 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
519613 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7337 519213 int32_t b=1;
7338
7339
2/2
✓ Branch 0 taken 276528 times.
✓ Branch 1 taken 242685 times.
519213 if(x&8) b<<=2;
7340
7341
2/2
✓ Branch 0 taken 220331 times.
✓ Branch 1 taken 298882 times.
519213 if(y&8) b<<=1;
7342
7343
3/4
✓ Branch 0 taken 450224 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 450224 times.
519213 if(((c->walk>>4)&b) && !dried)
7344 450224 return true;
7345
7346
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7347
7348 ++pos;
7349
7350 if(!(x&8))
7351 b<<=2;
7352 else
7353 {
7354 c = &combobuf[m->data[pos]];
7355 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7356 b=1;
7357
7358 if(y&8) b<<=1;
7359 }
7360
7361 return ((c->walk>>4)&b) ? !dried : false;
7362 519213 }
7363
7364 860420 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7365 {
7366 860420 int max_x = world_w;
7367 860420 int max_y = world_h;
7368
2/2
✓ Branch 0 taken 165182 times.
✓ Branch 1 taken 695238 times.
860420 if (!get_qr(qr_LTTPWALK))
7369 {
7370 695238 max_x -= 7;
7371 695238 max_y -= 7;
7372 695238 }
7373
2/4
✓ Branch 0 taken 860420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 860420 times.
860420 if (x < 0 || y < 0) return false;
7374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (x >= max_x) return false;
7375
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
860420 if (x >= max_x - 8 && cnt == 2) return false;
7376
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (y >= max_y) return false;
7377
7378
3/4
✓ Branch 0 taken 17860 times.
✓ Branch 1 taken 842560 times.
✓ Branch 2 taken 842560 times.
✗ Branch 3 not taken.
860420 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7379 860420 }
7380
7381 860420 bool water_walkflag(int32_t x, int32_t y)
7382 {
7383 860420 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7384 860420 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7385 860420 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7386
7387 860420 int32_t b=1;
7388
2/2
✓ Branch 0 taken 439102 times.
✓ Branch 1 taken 421318 times.
860420 if(x&8) b<<=2;
7389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if(y&8) b<<=1;
7390
7391
2/2
✓ Branch 0 taken 74192 times.
✓ Branch 1 taken 786228 times.
860420 if(get_qr(qr_NO_SOLID_SWIM))
7392 {
7393
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 73718 times.
74192 if(c.walk&b)
7394 474 return true;
7395
7396
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 72804 times.
73718 if(c1.walk&b)
7397 914 return true;
7398
7399
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 72733 times.
72804 if(c2.walk&b)
7400 71 return true;
7401 72733 }
7402 else
7403 {
7404
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7405 16371 return true;
7406
7407
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7408 17 return true;
7409
7410
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7411 13 return true;
7412 }
7413
7414 842560 return false;
7415 860420 }
7416
7417 589885 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7418 {
7419
2/2
✓ Branch 0 taken 100391 times.
✓ Branch 1 taken 489494 times.
589885 if(dlevel)
7420
8/8
✓ Branch 0 taken 488049 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 484722 times.
✓ Branch 3 taken 3327 times.
✓ Branch 4 taken 483005 times.
✓ Branch 5 taken 1717 times.
✓ Branch 6 taken 4386 times.
✓ Branch 7 taken 478619 times.
489494 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7421 10875 return true;
7422
7423
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 579008 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
579010 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7424 return true;
7425
7426
8/8
✓ Branch 0 taken 578724 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 578481 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 578270 times.
✓ Branch 5 taken 211 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 577874 times.
579010 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7427 1136 return true;
7428
7429 // for(int32_t i=0; i<4; i++)
7430
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 577033 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
577874 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7431 36 return true;
7432
7433
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 577837 times.
577838 if (collide_object(x, y,cnt*8, 1))
7434 1 return true;
7435
7436 577837 return _walkflag(x,y,cnt);
7437 589885 }
7438
7439 12220 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7440 {
7441 // 16 pixel buffer to account for slopes that are on bordering screens.
7442
4/8
✓ Branch 0 taken 12220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12220 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12220 times.
12220 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7443 return true;
7444
7445 // for(int32_t i=0; i<4; i++)
7446
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12220 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7447 return true;
7448
7449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
12220 if (collide_object(x, y,cnt*8, 1, ign))
7450 return true;
7451
7452 12220 return _walkflag(x,y,cnt);
7453 12220 }
7454
7455 39590 void map_bkgsfx(bool on)
7456 {
7457
2/2
✓ Branch 0 taken 39569 times.
✓ Branch 1 taken 21 times.
39590 if(on)
7458 {
7459 39569 cont_sfx(hero_scr->oceansfx);
7460
7461
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 39200 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
39569 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7462 315 cont_sfx(hero_scr->bosssfx);
7463 39569 }
7464 else
7465 {
7466 21 adjust_sfx(hero_scr->oceansfx,128,false);
7467 21 adjust_sfx(hero_scr->bosssfx,128,false);
7468
7469
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7470 {
7471
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7472 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7473 114 }
7474 }
7475 39590 }
7476
7477 261 void toggle_switches(dword flags, bool entry)
7478 {
7479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(!flags) return; //No flags to toggle
7480
7481 522 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7482 261 toggle_switches(flags, entry, create_screen_handles(scr));
7483 261 });
7484 261 }
7485 55206 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7486 {
7487
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 54275 times.
55206 if(!flags) return; //No flags to toggle
7488
7489 931 mapscr* m = screen_handles[0].base_scr;
7490 931 int screen = m->screen;
7491 931 bool is_active_screen = is_in_current_region(m);
7492
7493 525235 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7494 524304 byte togglegrid[176] = {0};
7495 524304 mapscr* scr = rpos_handle.scr;
7496 524304 int lyr = rpos_handle.layer;
7497 524304 int pos = rpos_handle.pos;
7498 524304 newcombo const& cmb = combobuf[scr->data[pos]];
7499
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 484880 times.
524304 if(is_active_screen)
7500
1/2
✓ Branch 0 taken 484880 times.
✗ Branch 1 not taken.
641011 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7501
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 156131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
156131 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7502 }, ctrigSWITCHSTATE);
7503
3/4
✓ Branch 0 taken 523592 times.
✓ Branch 1 taken 712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2809 times.
524304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7504
2/2
✓ Branch 0 taken 2809 times.
✓ Branch 1 taken 521495 times.
524304 && !(cmb.usrflags & cflag11)) //global state
7505 {
7506
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2363 times.
2809 if(flags&(1<<cmb.attribytes[0]))
7507 {
7508 2363 set<int32_t> oldData;
7509 //Increment the combo/cset by the attributes
7510 2363 int32_t cmbofs = (cmb.attributes[0]/10000L);
7511 2363 int32_t csofs = (cmb.attributes[1]/10000L);
7512
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 oldData.insert(scr->data[pos]);
7513
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7514 2363 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7515
4/4
✓ Branch 0 taken 1444 times.
✓ Branch 1 taken 919 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 238 times.
2363 if(entry && (cmb.usrflags&cflag8))
7516 {
7517 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7518
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7519 {
7520 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7521 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7522 if(oldData.find(cid) != oldData.end())
7523 break;
7524
7525 scr->data[pos] = cid;
7526 if(!(tmp->animflags & AF_CYCLENOCSET))
7527 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7528 oldData.insert(cid);
7529 tmp = &combobuf[cid];
7530 }
7531 238 }
7532 2363 int32_t cmbid = scr->data[pos];
7533
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2322 times.
2363 if(combobuf[cmbid].animflags & AF_CYCLE)
7534 {
7535 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7536 41 combobuf[cmbid].cur_frame=0;
7537 41 combobuf[cmbid].aclk = 0;
7538
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7539 41 }
7540 2363 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7541
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1803 times.
2363 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7542
2/2
✓ Branch 0 taken 12621 times.
✓ Branch 1 taken 1803 times.
14424 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7543 {
7544
2/2
✓ Branch 0 taken 1803 times.
✓ Branch 1 taken 10818 times.
12621 if(lyr==lyr2) continue;
7545
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10474 times.
10818 if(!(cmb.usrflags&(1<<lyr2))) continue;
7546
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(togglegrid[pos]&(1<<lyr2)) continue;
7547
7548 344 mapscr* scr_2 = screen_handles[lyr2].scr;
7549
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7550 continue;
7551 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7552
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7553 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7554 continue; //This is a switch/block that will be hit later in the loop!
7555 344 set<int32_t> oldData2;
7556 //Increment the combo/cset by the original cmb's attributes
7557
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7558
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7559 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7560
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7561 {
7562 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7563 while(tmp->can_cycle())
7564 {
7565 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7566 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7567 if(oldData2.find(cid) != oldData2.end())
7568 break;
7569
7570 scr_2->data[pos] = cid;
7571 if(!(tmp->animflags & AF_CYCLENOCSET))
7572 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7573 oldData2.insert(cid);
7574 tmp = &combobuf[cid];
7575 }
7576 }
7577 344 int32_t cmbid2 = scr_2->data[pos];
7578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7579 {
7580 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7581 combobuf[cmbid2].cur_frame=0;
7582 combobuf[cmbid2].aclk = 0;
7583 combo_caches::drawing.refresh(cmbid2);
7584 }
7585 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7586 344 }
7587
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 560 times.
✓ Branch 2 taken 1803 times.
2363 }
7588 2249 }
7589 524304 });
7590
7591
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
931 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7592 {
7593 newcombo const& cmb = combobuf[mblock2.bcombo];
7594 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7595 {
7596 if(flags&(1<<cmb.attribytes[0]))
7597 {
7598 //Increment the combo/cset by the attributes
7599 int32_t cmbofs = (cmb.attributes[0]/10000L);
7600 int32_t csofs = (cmb.attributes[1]/10000L);
7601 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7602 mblock2.cs = (mblock2.cs + csofs) & 15;
7603 int32_t cmbid = mblock2.bcombo;
7604 if(combobuf[cmbid].animflags & AF_CYCLE)
7605 {
7606 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7607 combobuf[cmbid].cur_frame=0;
7608 combobuf[cmbid].aclk = 0;
7609 combo_caches::drawing.refresh(cmbid);
7610 }
7611 }
7612 }
7613 }
7614
7615
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 707 times.
931 if (is_active_screen)
7616 {
7617 707 int screen_index_offset = get_region_screen_offset(m->screen);
7618 707 word c = m->numFFC();
7619
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 707 times.
1272 for (int q = 0; q < c; ++q)
7620 {
7621 565 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7622
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
596 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7623
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
31 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7624 }, ctrigSWITCHSTATE);
7625 565 }
7626 707 }
7627 55206 }
7628
7629 1 void toggle_gswitches(int32_t state, bool entry)
7630 {
7631 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7632 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7633 1 });
7634 1 }
7635 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7636 {
7637 1 bool states[256] = {false};
7638 1 states[state] = true;
7639 1 toggle_gswitches(states, entry, screen_handles);
7640 1 }
7641 15796836 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7642 {
7643
1/2
✓ Branch 0 taken 15796836 times.
✗ Branch 1 not taken.
15796836 if(!states) return;
7644
7645 15796836 auto& combo_cache = combo_caches::gswitch;
7646 15796836 mapscr* base_scr = screen_handles[0].base_scr;
7647 15796836 int screen = base_scr->screen;
7648 15796836 bool is_active_screen = is_in_current_region(base_scr);
7649 15796836 byte togglegrid[176] = {0};
7650
2/2
✓ Branch 0 taken 15796836 times.
✓ Branch 1 taken 110577852 times.
126374688 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7651 {
7652 110577852 mapscr* scr = screen_handles[lyr].scr;
7653
2/2
✓ Branch 0 taken 35901270 times.
✓ Branch 1 taken 74676582 times.
110577852 if (!scr)
7654 74676582 continue;
7655
7656
2/2
✓ Branch 0 taken 35901270 times.
✓ Branch 1 taken 6318623520 times.
6354524790 for(int32_t pos = 0; pos < 176; ++pos)
7657 {
7658 6318623520 int cid = scr->data[pos];
7659 6318623520 auto& mini_cmb = combo_cache.minis[cid];
7660
7661
2/2
✓ Branch 0 taken 2910336 times.
✓ Branch 1 taken 6315713184 times.
6318623520 if (is_active_screen)
7662 {
7663
2/2
✓ Branch 0 taken 6315711302 times.
✓ Branch 1 taken 1882 times.
6315713184 if (mini_cmb.trigger_global_state)
7664 {
7665 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7666
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7668 }, ctrigSWITCHSTATE);
7669 1882 }
7670 6315713184 }
7671
7672
2/2
✓ Branch 0 taken 55356 times.
✓ Branch 1 taken 6318568164 times.
6318623520 if (!mini_cmb.has_global_state)
7673 6318568164 continue;
7674
7675 55356 newcombo const& cmb = combobuf[cid];
7676
2/4
✓ Branch 0 taken 55356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55356 times.
55356 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7677 {
7678 if(states[cmb.attribytes[0]])
7679 {
7680 set<int32_t> oldData;
7681 //Increment the combo/cset by the attributes
7682 int32_t cmbofs = (cmb.attributes[0]/10000L);
7683 int32_t csofs = (cmb.attributes[1]/10000L);
7684 oldData.insert(scr->data[pos]);
7685 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7686 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7687 if(entry && (cmb.usrflags&cflag8))
7688 {
7689 newcombo const* tmp = &combobuf[scr->data[pos]];
7690 while(tmp->can_cycle())
7691 {
7692 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7693 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7694 if(oldData.find(cid) != oldData.end())
7695 break;
7696 scr->data[pos] = cid;
7697 if(!(tmp->animflags & AF_CYCLENOCSET))
7698 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7699 oldData.insert(cid);
7700 tmp = &combobuf[cid];
7701 }
7702 }
7703 int32_t cmbid = scr->data[pos];
7704 if(combobuf[cmbid].animflags & AF_CYCLE)
7705 {
7706 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7707 combobuf[cmbid].cur_frame=0;
7708 combobuf[cmbid].aclk = 0;
7709 combo_caches::drawing.refresh(cmbid);
7710 }
7711 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7712 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7713 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7714 {
7715 if(lyr==lyr2) continue;
7716 if(!(cmb.usrflags&(1<<lyr2))) continue;
7717 if(togglegrid[pos]&(1<<lyr2)) continue;
7718 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7719 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7720 continue;
7721 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7722 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7723 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7724 continue; //This is a switch/block that will be hit later in the loop!
7725 set<int32_t> oldData2;
7726 //Increment the combo/cset by the original cmb's attributes
7727 oldData2.insert(scr_2->data[pos]);
7728 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7729 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7730 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7731 {
7732 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7733 while(tmp->can_cycle())
7734 {
7735 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7736 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7737 if(oldData2.find(cid) != oldData2.end())
7738 break;
7739 scr_2->data[pos] = cid;
7740 if(!(tmp->animflags & AF_CYCLENOCSET))
7741 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7742 oldData2.insert(cid);
7743 tmp = &combobuf[cid];
7744 }
7745 }
7746 int32_t cmbid2 = scr_2->data[pos];
7747 if(combobuf[cmbid2].animflags & AF_CYCLE)
7748 {
7749 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7750 combobuf[cmbid2].cur_frame=0;
7751 combobuf[cmbid2].aclk = 0;
7752 combo_caches::drawing.refresh(cmbid2);
7753 }
7754 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7755 }
7756 }
7757 }
7758 55356 }
7759 35901270 }
7760
7761
4/4
✓ Branch 0 taken 554661 times.
✓ Branch 1 taken 15242175 times.
✓ Branch 2 taken 549917 times.
✓ Branch 3 taken 4744 times.
15796836 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7762 {
7763 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7764
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7765 {
7766 if(states[cmb.attribytes[0]])
7767 {
7768 //Increment the combo/cset by the attributes
7769 int32_t cmbofs = (cmb.attributes[0]/10000L);
7770 int32_t csofs = (cmb.attributes[1]/10000L);
7771 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7772 mblock2.cs = (mblock2.cs + csofs) & 15;
7773 int32_t cmbid = mblock2.bcombo;
7774 if(combobuf[cmbid].animflags & AF_CYCLE)
7775 {
7776 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7777 combobuf[cmbid].cur_frame=0;
7778 combobuf[cmbid].aclk = 0;
7779 combo_caches::drawing.refresh(cmbid);
7780 }
7781 }
7782 }
7783 4744 }
7784
7785
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 15780677 times.
15796836 if(is_active_screen)
7786 {
7787 15780677 int screen_index_offset = get_region_screen_offset(screen);
7788 15780677 word c = base_scr->numFFC();
7789
2/2
✓ Branch 0 taken 455562886 times.
✓ Branch 1 taken 15780677 times.
471343563 for (int q = 0; q < c; ++q)
7790 {
7791 455562886 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7792
1/2
✓ Branch 0 taken 455562886 times.
✗ Branch 1 not taken.
455796224 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7793
1/2
✓ Branch 0 taken 233338 times.
✗ Branch 1 not taken.
233338 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7794 }, ctrigSWITCHSTATE);
7795 455562886 }
7796 15780677 }
7797 15796836 }
7798 54945 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7799 {
7800 bool states[256];
7801
2/2
✓ Branch 0 taken 14065920 times.
✓ Branch 1 taken 54945 times.
14120865 for(auto q = 0; q < 256; ++q)
7802 {
7803 14065920 states[q] = game->gswitch_timers[q] != 0;
7804 14065920 }
7805 54945 toggle_gswitches(states, true, screen_handles);
7806 54945 }
7807 15352522 void run_gswitch_timers()
7808 {
7809 15352522 bool states[256] = {false};
7810 15352522 auto& m = game->gswitch_timers.mut_inner();
7811
2/2
✓ Branch 0 taken 3926146816 times.
✓ Branch 1 taken 15352522 times.
3941499338 for(auto it = m.begin(); it != m.end();)
7812 {
7813
2/2
✓ Branch 0 taken 3926146216 times.
✓ Branch 1 taken 600 times.
3926146816 if(it->second > 0)
7814
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7815 {
7816 1 states[it->first] = true;
7817 1 it = m.erase(it);
7818 1 continue;
7819 }
7820 3926146815 ++it;
7821 }
7822 31094412 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7823 15741890 toggle_gswitches(states, false, create_screen_handles(scr));
7824 15741890 });
7825 15352522 }
7826 1150 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7827 {
7828
2/2
✓ Branch 0 taken 294400 times.
✓ Branch 1 taken 1150 times.
295550 for(auto q = 0; q < 256; ++q)
7829 {
7830
1/2
✓ Branch 0 taken 294400 times.
✗ Branch 1 not taken.
294400 if(game->gswitch_timers[q] > 0)
7831 game->gswitch_timers[q] = 0;
7832 294400 }
7833 1150 }
7834
7835 /**** View Map ****/
7836
7837 int32_t mapres = 0;
7838 int32_t view_map_show_mode = 3;
7839
7840 129280 bool displayOnMap(int32_t x, int32_t y)
7841 {
7842 129280 int32_t s = (y<<4) + x;
7843 129280 int mi = mapind(cur_map, s);
7844
2/2
✓ Branch 0 taken 70863 times.
✓ Branch 1 taken 58417 times.
129280 if (!(game->maps[mi]&mVISITED))
7845 70863 return false;
7846
7847 // Don't display if not part of DMap
7848
4/4
✓ Branch 0 taken 15807 times.
✓ Branch 1 taken 42610 times.
✓ Branch 2 taken 4750 times.
✓ Branch 3 taken 4311 times.
67478 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7849
1/2
✓ Branch 0 taken 15807 times.
✗ Branch 1 not taken.
15807 (DMaps[cur_dmap].type != dmOVERW) &&
7850
2/2
✓ Branch 0 taken 12631 times.
✓ Branch 1 taken 3176 times.
15807 !(x >= DMaps[cur_dmap].xoff &&
7851
2/2
✓ Branch 0 taken 9061 times.
✓ Branch 1 taken 3570 times.
12631 x < DMaps[cur_dmap].xoff+8 &&
7852 9061 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7853 11057 return false;
7854 else
7855 47360 return true;
7856 129280 }
7857
7858 1010 void ViewMap()
7859 {
7860 1010 ViewingMap = true;
7861
7862 1010 BITMAP* mappic = NULL;
7863 static double scales[17] =
7864 {
7865 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7866 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7867 };
7868
7869 // Cursor position for hero, in absolute map coordinates.
7870 1010 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7871 1010 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7872
7873 int32_t px;
7874 int32_t py;
7875
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1010 times.
1010 if (is_in_scrolling_region())
7876 {
7877 // Center the player on the middle of the map view.
7878 px = (16*256/2 - lx) * 2;
7879 py = (8*176/2 - ly) * 2;
7880 }
7881 else
7882 {
7883 // Center the current screen on the middle of the map view.
7884 1010 px = ((8-(cur_screen&15)) << 9) - 256;
7885 1010 py = ((4-(cur_screen>>4)) * 352) - 176;
7886 }
7887
7888 1010 int32_t sc = 6;
7889
7890 1010 bool done=false, redraw=true;
7891
7892 1010 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7893
7894
1/2
✓ Branch 0 taken 1010 times.
✗ Branch 1 not taken.
1010 if(!mappic)
7895 {
7896 enter_sys_pal();
7897 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7898 exit_sys_pal();
7899 return;
7900 }
7901
7902 1010 clear_to_color(mappic, WHITE);
7903
7904 1010 auto prev_viewport = viewport;
7905 1010 viewport.x = 0;
7906 1010 viewport.y = 0;
7907
7908 // draw the map
7909 1010 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7910 1010 combotile_add_x = 256;
7911 1010 combotile_add_y = 0;
7912 1010 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7913
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 1010 times.
9090 for(int32_t y=0; y<8; y++)
7914 {
7915
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 129280 times.
137360 for(int32_t x=0; x<16; x++)
7916 {
7917
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 81920 times.
129280 if (!displayOnMap(x, y))
7918 81920 continue;
7919
7920 47360 int screen = map_scr_xy_to_index(x, y);
7921 47360 auto scrs = loadscr2(screen);
7922 47360 mapscr* scr = &scrs[0];
7923
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!scr->is_valid())
7924 continue;
7925
7926 screen_handles_t screen_handles;
7927
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i <= 6; i++)
7928
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7929
7930 47360 int xx = 0;
7931 47360 int yy = -playing_field_offset;
7932
7933
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if (!classic_draw)
7934 for (int layer = -7; layer <= -4; ++layer)
7935 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7936
7937
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if(classic_draw)
7938 {
7939
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 47313 times.
47360 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7940
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7941
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7942 47360 }
7943
7944
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 47147 times.
47360 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7945
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7946
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7947
7948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47360 times.
47360 if(!classic_draw)
7949 {
7950 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7951 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7952 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7953 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7954 }
7955
7956
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7957
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7958
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7959
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7960
7961
2/2
✓ Branch 0 taken 47313 times.
✓ Branch 1 taken 47 times.
47360 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7962 {
7963
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7964
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7965 47313 }
7966
7967
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 putscrdoors(scr, screen_bmp, xx, yy);
7968
2/2
✓ Branch 0 taken 43358 times.
✓ Branch 1 taken 4002 times.
47360 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7969 {
7970
1/2
✓ Branch 0 taken 43358 times.
✗ Branch 1 not taken.
43358 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7971
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 39896 times.
43358 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7972 {
7973
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7974
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7975 3462 }
7976 43358 }
7977
7978
2/2
✓ Branch 0 taken 47147 times.
✓ Branch 1 taken 213 times.
47360 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7979 {
7980
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7981
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7982 47147 }
7983
7984
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7985
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7986
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7987
2/2
✓ Branch 0 taken 7464 times.
✓ Branch 1 taken 39896 times.
47360 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7988 {
7989
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7990
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7991 7464 }
7992
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7993
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7994
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1680 times.
✓ Branch 3 taken 45680 times.
47360 if(replay_version_check(40))
7995
1/2
✓ Branch 0 taken 1680 times.
✗ Branch 1 not taken.
1680 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
7996
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7997
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7998
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7999
8000
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
8001
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
47360 }
8002 8080 }
8003
8004 1010 viewport = prev_viewport;
8005 1010 combotile_add_x = 0;
8006 1010 combotile_add_y = 0;
8007
8008 1010 destroy_bitmap(screen_bmp);
8009 1010 clear_keybuf();
8010 1010 pause_all_sfx();
8011
8012 // view it
8013 1010 int32_t delay = 0;
8014
8015 1010 do
8016 {
8017
2/2
✓ Branch 0 taken 189085 times.
✓ Branch 1 taken 29891 times.
218976 if (replay_version_check(0, 11))
8018 29891 load_control_state();
8019
8020 218976 int32_t step = int32_t(16.0/scales[sc]);
8021 218976 step = (step>>1) + (step&1);
8022 218976 bool r = cRbtn();
8023
8024
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(cLbtn())
8025 {
8026 step <<= 2;
8027 delay = 0;
8028 }
8029
8030
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218976 times.
218976 if(r)
8031 {
8032 if(rUp())
8033 {
8034 py+=step;
8035 redraw=true;
8036 }
8037
8038 if(rDown())
8039 {
8040 py-=step;
8041 redraw=true;
8042 }
8043
8044 if(rLeft())
8045 {
8046 px+=step;
8047 redraw=true;
8048 }
8049
8050 if(rRight())
8051 {
8052 px-=step;
8053 redraw=true;
8054 }
8055 }
8056 else
8057 {
8058
2/2
✓ Branch 0 taken 203528 times.
✓ Branch 1 taken 15448 times.
218976 if(Up())
8059 {
8060 15448 py+=step;
8061 15448 redraw=true;
8062 15448 }
8063
8064
2/2
✓ Branch 0 taken 203410 times.
✓ Branch 1 taken 15566 times.
218976 if(Down())
8065 {
8066 15566 py-=step;
8067 15566 redraw=true;
8068 15566 }
8069
8070
2/2
✓ Branch 0 taken 191540 times.
✓ Branch 1 taken 27436 times.
218976 if(Left())
8071 {
8072 27436 px+=step;
8073 27436 redraw=true;
8074 27436 }
8075
8076
2/2
✓ Branch 0 taken 192194 times.
✓ Branch 1 taken 26782 times.
218976 if(Right())
8077 {
8078 26782 px-=step;
8079 26782 redraw=true;
8080 26782 }
8081 }
8082
8083
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 196932 times.
218976 if(delay)
8084 22044 --delay;
8085 else
8086 {
8087 196932 bool a = cAbtn();
8088 196932 bool b = cBbtn();
8089
8090
3/4
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 195146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1786 times.
196932 if(a && !b)
8091 {
8092
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 sc=zc_min(sc+1,16);
8093 1786 delay=8;
8094 1786 redraw=true;
8095 1786 }
8096
8097
3/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 195960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 972 times.
196932 if(b && !a)
8098 {
8099
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 1 times.
972 sc=zc_max(sc-1,0);
8100 972 delay=8;
8101 972 redraw=true;
8102 972 }
8103 }
8104
8105
2/2
✓ Branch 0 taken 218965 times.
✓ Branch 1 taken 11 times.
218976 if(rPbtn())
8106 11 --view_map_show_mode;
8107
8108 218976 px = vbound(px,-4096,4096);
8109 218976 py = vbound(py,-1408,1408);
8110
8111 218976 double scale = scales[sc];
8112
8113
2/2
✓ Branch 0 taken 75341 times.
✓ Branch 1 taken 143635 times.
218976 if(!redraw)
8114 {
8115 143635 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8116 143635 }
8117 else
8118 {
8119 75341 clear_to_color(framebuf,BLACK);
8120 150682 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8121 75341 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8122 75341 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8123
8124 75341 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8125 75341 redraw=false;
8126 }
8127
8128 218976 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8129 218976 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8130
8131
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 211510 times.
218976 if(view_map_show_mode&1)
8132 {
8133 211510 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8134 211510 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8135 211510 }
8136
8137
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 213376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
218976 if(view_map_show_mode&2 || r)
8138 213376 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8139
8140
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(r)
8141 {
8142 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8143 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8144 }
8145
8146 218976 advanceframe(false, false);
8147
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 189085 times.
218976 if (replay_version_check(11))
8148 189085 load_control_state();
8149
8150
2/2
✓ Branch 0 taken 217967 times.
✓ Branch 1 taken 1009 times.
218976 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8151 1009 done = true;
8152
8153
2/2
✓ Branch 0 taken 217966 times.
✓ Branch 1 taken 1010 times.
437952 }
8154
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 217967 times.
218976 while(!done && !Quit);
8155
8156 1010 ViewingMap = false;
8157 1010 destroy_bitmap(mappic);
8158 1010 resume_all_sfx();
8159 1010 }
8160
8161 1112 int32_t onViewMap()
8162 {
8163
4/6
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 1010 times.
1112 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8164 {
8165 1010 clear_to_color(framebuf,BLACK);
8166 1010 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8167 1010 advanceframe(true);
8168 1010 ViewMap();
8169 1010 }
8170
8171 1112 return D_O_K;
8172 }
8173
8174 38959418 bool isGrassType(int32_t type)
8175 {
8176
2/2
✓ Branch 0 taken 38201305 times.
✓ Branch 1 taken 758113 times.
38959418 switch(type)
8177 {
8178 case cTALLGRASS:
8179 case cTALLGRASSNEXT:
8180 case cTALLGRASSTOUCHY:
8181 758113 return true;
8182 }
8183
8184 38201305 return false;
8185 38959418 }
8186
8187 25672 bool isFlowersType(int32_t type)
8188 {
8189
2/2
✓ Branch 0 taken 21332 times.
✓ Branch 1 taken 4340 times.
25672 switch(type)
8190 {
8191 case cFLOWERS:
8192 case cFLOWERSTOUCHY:
8193 4340 return true;
8194 }
8195
8196 21332 return false;
8197 25672 }
8198
8199 bool isGenericType(int32_t type)
8200 {
8201 switch(type)
8202 {
8203 case cTRIGGERGENERIC:
8204 return true;
8205 }
8206
8207 return false;
8208 }
8209
8210 30978 bool isBushType(int32_t type)
8211 {
8212
2/2
✓ Branch 0 taken 25672 times.
✓ Branch 1 taken 5306 times.
30978 switch(type)
8213 {
8214 case cBUSH:
8215 case cBUSHNEXT:
8216 case cBUSHTOUCHY:
8217 case cBUSHNEXTTOUCHY:
8218
8219 5306 return true;
8220 }
8221
8222 25672 return false;
8223 30978 }
8224
8225 bool isSlashType(int32_t type)
8226 {
8227 switch(type)
8228 {
8229 case cSLASH:
8230 case cSLASHITEM:
8231 case cSLASHTOUCHY:
8232 case cSLASHITEMTOUCHY:
8233 case cSLASHNEXT:
8234 case cSLASHNEXTITEM:
8235 case cSLASHNEXTTOUCHY:
8236 case cSLASHNEXTITEMTOUCHY:
8237 return true;
8238 }
8239
8240 return false;
8241 }
8242
8243 18151 bool isCuttableNextType(int32_t type)
8244 {
8245
2/2
✓ Branch 0 taken 9830 times.
✓ Branch 1 taken 8321 times.
18151 switch(type)
8246 {
8247 case cSLASHNEXT:
8248 case cSLASHNEXTITEM:
8249 case cTALLGRASSNEXT:
8250 case cBUSHNEXT:
8251 case cSLASHNEXTTOUCHY:
8252 case cSLASHNEXTITEMTOUCHY:
8253 case cBUSHNEXTTOUCHY:
8254 8321 return true;
8255 }
8256
8257 9830 return false;
8258 18151 }
8259
8260 20007 bool isTouchyType(int32_t type)
8261 {
8262
2/2
✓ Branch 0 taken 8508 times.
✓ Branch 1 taken 11499 times.
20007 switch(type)
8263 {
8264 case cSLASHTOUCHY:
8265 case cSLASHITEMTOUCHY:
8266 case cBUSHTOUCHY:
8267 case cFLOWERSTOUCHY:
8268 case cTALLGRASSTOUCHY:
8269 case cSLASHNEXTTOUCHY:
8270 case cSLASHNEXTITEMTOUCHY:
8271 case cBUSHNEXTTOUCHY:
8272 11499 return true;
8273 }
8274
8275 8508 return false;
8276 20007 }
8277
8278 38867592 bool isCuttableType(int32_t type)
8279 {
8280
2/2
✓ Branch 0 taken 38414561 times.
✓ Branch 1 taken 453031 times.
38867592 switch(type)
8281 {
8282 case cSLASH:
8283 case cSLASHITEM:
8284 case cBUSH:
8285 case cFLOWERS:
8286 case cTALLGRASS:
8287 case cTALLGRASSNEXT:
8288 case cSLASHNEXT:
8289 case cSLASHNEXTITEM:
8290 case cBUSHNEXT:
8291
8292 case cSLASHTOUCHY:
8293 case cSLASHITEMTOUCHY:
8294 case cBUSHTOUCHY:
8295 case cFLOWERSTOUCHY:
8296 case cTALLGRASSTOUCHY:
8297 case cSLASHNEXTTOUCHY:
8298 case cSLASHNEXTITEMTOUCHY:
8299 case cBUSHNEXTTOUCHY:
8300 453031 return true;
8301 }
8302
8303 38414561 return false;
8304 38867592 }
8305
8306 19783 bool isCuttableItemType(int32_t type)
8307 {
8308
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 19331 times.
19783 switch(type)
8309 {
8310 case cSLASHITEM:
8311 case cBUSH:
8312 case cFLOWERS:
8313 case cTALLGRASS:
8314 case cTALLGRASSNEXT:
8315 case cSLASHNEXTITEM:
8316 case cBUSHNEXT:
8317
8318 case cSLASHITEMTOUCHY:
8319 case cBUSHTOUCHY:
8320 case cFLOWERSTOUCHY:
8321 case cTALLGRASSTOUCHY:
8322 case cSLASHNEXTITEMTOUCHY:
8323 case cBUSHNEXTTOUCHY:
8324 19331 return true;
8325 }
8326
8327 452 return false;
8328 19783 }
8329
8330 69 bool is_push(mapscr* m, int32_t pos)
8331 {
8332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(m->sflag[pos]))
8333 return true;
8334 69 newcombo const& cmb = combobuf[m->data[pos]];
8335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(cmb.flag))
8336 return true;
8337
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 55 times.
69 if(cmb.type == cPUSHBLOCK)
8338 14 return true;
8339
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
55 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8340 return true; //Counts as 'pushblock' flag
8341 55 return false;
8342 69 }
8343
8344 428 static std::map<int, screen_state_t> screen_states;
8345
8346 37532 std::map<int, screen_state_t>& get_screen_states()
8347 {
8348 37532 return screen_states;
8349 }
8350
8351 45813519 screen_state_t& get_screen_state(int screen)
8352 {
8353 45813519 return screen_states[screen];
8354 }
8355
8356 609 void clear_screen_states()
8357 {
8358 609 screen_states.clear();
8359 609 }
8360
8361 1597 void screen_item_set_state(int screen, ScreenItemState state)
8362 {
8363 1597 get_screen_state(screen).item_state = state;
8364 1597 }
8365
8366 557171 void mark_visited(int screen)
8367 {
8368
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 556696 times.
557171 if (screen < 0x80)
8369 {
8370
3/4
✓ Branch 0 taken 556696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 459777 times.
✓ Branch 3 taken 96919 times.
556696 if(!get_qr(qr_ONLY_MARK_SCREENS_VISITED_IF_MAP_VIEWABLE) || (DMaps[cur_dmap].flags&dmfVIEWMAP))
8371 459777 game->maps[mapind(cur_map, screen)] |= mVISITED;
8372
8373 556696 markBmap(-1, screen);
8374 556696 }
8375 557171 }
8376